` without `tabindex` set).
- if (relatedTarget) {
- const el = findDOMNode(editor)
-
- // COMPAT: The event should be ignored if the focus is returning to the
- // editor from an embedded editable element (eg. an
element inside
- // a void node).
- if (relatedTarget == el) return true
-
- // COMPAT: The event should be ignored if the focus is moving from the
- // editor to inside a void node's spacer element.
- if (relatedTarget.hasAttribute('data-slate-spacer')) return true
-
- // COMPAT: The event should be ignored if the focus is moving to a non-
- // editable section of an element that isn't a void node (eg. a list item
- // of the check list example).
- const node = findNode(relatedTarget, value)
- if (el.contains(relatedTarget) && node && !schema.isVoid(node))
- return true
- }
-
- debug('onBlur', { event })
- }
-
- /**
- * On change.
- *
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onChange(change, editor) {
- const { value } = change
-
- // If the value's schema isn't the editor's schema, update it. This can
- // happen on the initialization of the editor, or if the schema changes.
- // This change isn't save into history since only schema is updated.
- if (value.schema != editor.schema) {
- change.withoutSaving(() => {
- change.setValue({ schema: editor.schema }).normalize()
- })
- }
-
- debug('onChange')
- }
-
- /**
- * On composition end.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onCompositionEnd(event, change, editor) {
- const n = compositionCount
-
- // The `count` check here ensures that if another composition starts
- // before the timeout has closed out this one, we will abort unsetting the
- // `isComposing` flag, since a composition is still in affect.
- window.requestAnimationFrame(() => {
- if (compositionCount > n) return
- isComposing = false
-
- // HACK: we need to re-render the editor here so that it will update its
- // placeholder in case one is currently rendered. This should be handled
- // differently ideally, in a less invasive way?
- // (apply force re-render if isComposing changes)
- if (editor.state.isComposing) {
- editor.setState({ isComposing: false })
- }
- })
-
- debug('onCompositionEnd', { event })
- }
-
- /**
- * On composition start.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onCompositionStart(event, change, editor) {
- isComposing = true
- compositionCount++
-
- // HACK: we need to re-render the editor here so that it will update its
- // placeholder in case one is currently rendered. This should be handled
- // differently ideally, in a less invasive way?
- // (apply force re-render if isComposing changes)
- if (!editor.state.isComposing) {
- editor.setState({ isComposing: true })
- }
-
- debug('onCompositionStart', { event })
- }
-
- /**
- * On copy.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onCopy(event, change, editor) {
- const window = getWindow(event.target)
- isCopying = true
- window.requestAnimationFrame(() => (isCopying = false))
-
- debug('onCopy', { event })
- }
-
- /**
- * On cut.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onCut(event, change, editor) {
- if (editor.props.readOnly) return true
-
- const window = getWindow(event.target)
- isCopying = true
- window.requestAnimationFrame(() => (isCopying = false))
-
- debug('onCut', { event })
- }
-
- /**
- * On drag end.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragEnd(event, change, editor) {
- isDragging = false
-
- debug('onDragEnd', { event })
- }
-
- /**
- * On drag enter.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragEnter(event, change, editor) {
- debug('onDragEnter', { event })
- }
-
- /**
- * On drag exit.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragExit(event, change, editor) {
- debug('onDragExit', { event })
- }
-
- /**
- * On drag leave.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragLeave(event, change, editor) {
- debug('onDragLeave', { event })
- }
-
- /**
- * On drag over.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragOver(event, change, editor) {
- // If the target is inside a void node, and only in this case,
- // call `preventDefault` to signal that drops are allowed.
- // When the target is editable, dropping is already allowed by
- // default, and calling `preventDefault` hides the cursor.
- const { value } = editor
- const { schema } = value
- const node = findNode(event.target, editor.value)
- if (schema.isVoid(node)) event.preventDefault()
-
- // COMPAT: IE won't call onDrop on contentEditables unless the
- // default dragOver is prevented:
- // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/913982/
- // (2018/07/11)
- if (IS_IE) event.preventDefault()
-
- // If a drag is already in progress, don't do this again.
- if (!isDragging) {
- isDragging = true
-
- // COMPAT: IE will raise an `unspecified error` if dropEffect is
- // set. (2018/07/11)
- if (!IS_IE) {
- event.nativeEvent.dataTransfer.dropEffect = 'move'
- }
- }
-
- debug('onDragOver', { event })
- }
-
- /**
- * On drag start.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDragStart(event, change, editor) {
- isDragging = true
-
- debug('onDragStart', { event })
- }
-
- /**
- * On drop.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onDrop(event, change, editor) {
- // Nothing happens in read-only mode.
- if (editor.props.readOnly) return true
-
- // Prevent default so the DOM's value isn't corrupted.
- event.preventDefault()
-
- debug('onDrop', { event })
- }
-
- /**
- * On focus.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onFocus(event, change, editor) {
- if (isCopying) return true
- if (editor.props.readOnly) return true
-
- const el = findDOMNode(editor)
-
- // Save the new `activeElement`.
- const window = getWindow(event.target)
- activeElement = window.document.activeElement
-
- // COMPAT: If the editor has nested editable elements, the focus can go to
- // those elements. In Firefox, this must be prevented because it results in
- // issues with keyboard navigation. (2017/03/30)
- if (IS_FIREFOX && event.target != el) {
- el.focus()
- return true
- }
-
- debug('onFocus', { event })
- }
-
- /**
- * On input.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onInput(event, change, editor) {
- if (isComposing) return true
- if (change.value.selection.isBlurred) return true
-
- debug('onInput', { event })
- }
-
- /**
- * On key down.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onKeyDown(event, change, editor) {
- if (editor.props.readOnly) return true
-
- // When composing, we need to prevent all hotkeys from executing while
- // typing. However, certain characters also move the selection before
- // we're able to handle it, so prevent their default behavior.
- if (isComposing) {
- if (Hotkeys.isCompose(event)) event.preventDefault()
- return true
- }
-
- // Certain hotkeys have native editing behaviors in `contenteditable`
- // elements which will change the DOM and cause our value to be out of sync,
- // so they need to always be prevented.
- if (
- !IS_IOS &&
- (Hotkeys.isBold(event) ||
- Hotkeys.isDeleteBackward(event) ||
- Hotkeys.isDeleteForward(event) ||
- Hotkeys.isDeleteLineBackward(event) ||
- Hotkeys.isDeleteLineForward(event) ||
- Hotkeys.isDeleteWordBackward(event) ||
- Hotkeys.isDeleteWordForward(event) ||
- Hotkeys.isItalic(event) ||
- Hotkeys.isRedo(event) ||
- Hotkeys.isSplitBlock(event) ||
- Hotkeys.isTransposeCharacter(event) ||
- Hotkeys.isUndo(event))
- ) {
- event.preventDefault()
- }
-
- debug('onKeyDown', { event })
- }
-
- /**
- * On paste.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onPaste(event, change, editor) {
- if (editor.props.readOnly) return true
-
- // Prevent defaults so the DOM state isn't corrupted.
- event.preventDefault()
-
- debug('onPaste', { event })
- }
-
- /**
- * On select.
- *
- * @param {Event} event
- * @param {Change} change
- * @param {Editor} editor
- */
-
- function onSelect(event, change, editor) {
- if (isCopying) return true
- if (isComposing) return true
- if (editor.props.readOnly) return true
-
- // Save the new `activeElement`.
- const window = getWindow(event.target)
- activeElement = window.document.activeElement
-
- debug('onSelect', { event })
- }
-
- /**
- * Return the plugin.
- *
- * @type {Object}
- */
-
- return {
- onBeforeInput,
- onBlur,
- onChange,
- onCompositionEnd,
- onCompositionStart,
- onCopy,
- onCut,
- onDragEnd,
- onDragEnter,
- onDragExit,
- onDragLeave,
- onDragOver,
- onDragStart,
- onDrop,
- onFocus,
- onInput,
- onKeyDown,
- onPaste,
- onSelect,
- }
-}
-
-/**
- * Export.
- *
- * @type {Object}
- */
-
-export default BeforePlugin
diff --git a/packages/slate-react/src/plugins/after.js b/packages/slate-react/src/plugins/browser.js
similarity index 55%
rename from packages/slate-react/src/plugins/after.js
rename to packages/slate-react/src/plugins/browser.js
index 247fdd7e4..21e5a1792 100644
--- a/packages/slate-react/src/plugins/after.js
+++ b/packages/slate-react/src/plugins/browser.js
@@ -1,13 +1,16 @@
import Base64 from 'slate-base64-serializer'
import Debug from 'debug'
-import Plain from 'slate-plain-serializer'
-import { IS_IOS } from 'slate-dev-environment'
-import React from 'react'
-import getWindow from 'get-window'
-import { Text } from 'slate'
import Hotkeys from 'slate-hotkeys'
+import Plain from 'slate-plain-serializer'
+import ReactDOM from 'react-dom'
+import getWindow from 'get-window'
+import {
+ IS_FIREFOX,
+ IS_IE,
+ IS_IOS,
+ HAS_INPUT_EVENTS_LEVEL_2,
+} from 'slate-dev-environment'
-import Content from '../components/content'
import cloneFragment from '../utils/clone-fragment'
import findDOMNode from '../utils/find-dom-node'
import findNode from '../utils/find-node'
@@ -23,15 +26,20 @@ import setEventTransfer from '../utils/set-event-transfer'
* @type {Function}
*/
-const debug = Debug('slate:after')
+const debug = Debug('slate:browser')
/**
- * The after plugin.
+ * A plugin that adds the browser-specific logic to the editor.
*
* @return {Object}
*/
-function AfterPlugin() {
+function BrowserPlugin() {
+ let activeElement = null
+ let compositionCount = 0
+ let isComposing = false
+ let isCopying = false
+ let isDragging = false
let isDraggingInternally = null
/**
@@ -39,13 +47,25 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onBeforeInput(event, change, editor) {
+ function onBeforeInput(event, change, next) {
+ const { editor, value } = change
+ const isSynthetic = !!event.nativeEvent
+ if (editor.readOnly) return true
+
+ // COMPAT: If the browser supports Input Events Level 2, we will have
+ // attached a custom handler for the real `beforeinput` events, instead of
+ // allowing React's synthetic polyfill, so we need to ignore synthetics.
+ if (isSynthetic && HAS_INPUT_EVENTS_LEVEL_2) return true
+
debug('onBeforeInput', { event })
- const isSynthetic = !!event.nativeEvent
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
// If the event is synthetic, it's React's polyfill of `beforeinput` that
// isn't a true `beforeinput` event with meaningful information. It only
@@ -63,9 +83,8 @@ function AfterPlugin() {
event.preventDefault()
- const { value } = change
- const { document, selection, schema } = value
- const range = findRange(targetRange, value)
+ const { document, selection } = value
+ const range = findRange(targetRange, editor)
switch (event.inputType) {
case 'deleteByDrag':
@@ -103,7 +122,7 @@ function AfterPlugin() {
case 'insertParagraph': {
const hasVoidParent = document.hasVoidParent(
selection.start.path,
- schema
+ editor
)
if (hasVoidParent) {
@@ -147,13 +166,89 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onBlur(event, change, editor) {
+ function onBlur(event, change, next) {
+ const { editor } = change
+ if (isCopying) return true
+ if (editor.readOnly) return true
+
+ const { relatedTarget, target } = event
+ const window = getWindow(target)
+
+ // COMPAT: If the current `activeElement` is still the previous one, this is
+ // due to the window being blurred when the tab itself becomes unfocused, so
+ // we want to abort early to allow to editor to stay focused when the tab
+ // becomes focused again.
+ if (activeElement === window.document.activeElement) return true
+
+ // COMPAT: The `relatedTarget` can be null when the new focus target is not
+ // a "focusable" element (eg. a `
` without `tabindex` set).
+ if (relatedTarget) {
+ const el = ReactDOM.findDOMNode(editor)
+
+ // COMPAT: The event should be ignored if the focus is returning to the
+ // editor from an embedded editable element (eg. an
element inside
+ // a void node).
+ if (relatedTarget === el) return true
+
+ // COMPAT: The event should be ignored if the focus is moving from the
+ // editor to inside a void node's spacer element.
+ if (relatedTarget.hasAttribute('data-slate-spacer')) return true
+
+ // COMPAT: The event should be ignored if the focus is moving to a non-
+ // editable section of an element that isn't a void node (eg. a list item
+ // of the check list example).
+ const node = findNode(relatedTarget, editor)
+ if (el.contains(relatedTarget) && node && !change.isVoid(node))
+ return true
+ }
+
debug('onBlur', { event })
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
change.blur()
+ return true
+ }
+
+ /**
+ * On composition end.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onCompositionEnd(event, change, next) {
+ const { editor } = change
+ const n = compositionCount
+
+ // The `count` check here ensures that if another composition starts
+ // before the timeout has closed out this one, we will abort unsetting the
+ // `isComposing` flag, since a composition is still in affect.
+ window.requestAnimationFrame(() => {
+ if (compositionCount > n) return
+ isComposing = false
+
+ // HACK: we need to re-render the editor here so that it will update its
+ // placeholder in case one is currently rendered. This should be handled
+ // differently ideally, in a less invasive way?
+ // (apply force re-render if isComposing changes)
+ if (editor.state.isComposing) {
+ editor.setState({ isComposing: false })
+ }
+ })
+
+ debug('onCompositionEnd', { event })
+
+ // Delegate to the plugins stack.
+ return next()
}
/**
@@ -161,25 +256,28 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onClick(event, change, editor) {
- if (editor.props.readOnly) {
- return true
- }
+ function onClick(event, change, next) {
+ debug('onClick', { event })
- const { value } = change
- const { document, schema } = value
- const node = findNode(event.target, value)
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
- if (!node) {
- return
- }
+ const { editor } = change
+ if (editor.readOnly) return true
+
+ const { value } = editor
+ const { document } = value
+ const node = findNode(event.target, editor)
+ if (!node) return true
const ancestors = document.getAncestors(node.key)
const isVoid =
- node && (schema.isVoid(node) || ancestors.some(a => schema.isVoid(a)))
+ node && (change.isVoid(node) || ancestors.some(a => change.isVoid(a)))
if (isVoid) {
// COMPAT: In Chrome & Safari, selections that are at the zero offset of
@@ -189,7 +287,35 @@ function AfterPlugin() {
change.focus().moveToEndOfNode(node)
}
- debug('onClick', { event })
+ return true
+ }
+
+ /**
+ * On composition start.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onCompositionStart(event, change, next) {
+ isComposing = true
+ compositionCount++
+ const { editor } = change
+
+ // HACK: we need to re-render the editor here so that it will update its
+ // placeholder in case one is currently rendered. This should be handled
+ // differently ideally, in a less invasive way?
+ // (apply force re-render if isComposing changes)
+ if (!editor.state.isComposing) {
+ editor.setState({ isComposing: true })
+ }
+
+ debug('onCompositionStart', { event })
+
+ // Delegate to the plugins stack.
+ return next()
}
/**
@@ -197,13 +323,24 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onCopy(event, change, editor) {
+ function onCopy(event, change, next) {
+ const window = getWindow(event.target)
+ isCopying = true
+ window.requestAnimationFrame(() => (isCopying = false))
+
debug('onCopy', { event })
- cloneFragment(event, change.value)
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { editor } = change
+ cloneFragment(event, editor)
+ return true
}
/**
@@ -211,22 +348,34 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onCut(event, change, editor) {
+ function onCut(event, change, next) {
+ const { editor } = change
+ if (editor.readOnly) return true
+
+ const window = getWindow(event.target)
+ isCopying = true
+ window.requestAnimationFrame(() => (isCopying = false))
+
debug('onCut', { event })
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
// Once the fake cut content has successfully been added to the clipboard,
// delete the content in the current selection.
- cloneFragment(event, change.value, change.value.fragment, () => {
+ cloneFragment(event, editor, () => {
// If user cuts a void block node or a void inline node,
// manually removes it since selection is collapsed in this case.
const { value } = change
- const { endBlock, endInline, selection, schema } = value
+ const { endBlock, endInline, selection } = value
const { isCollapsed } = selection
- const isVoidBlock = endBlock && schema.isVoid(endBlock) && isCollapsed
- const isVoidInline = endInline && schema.isVoid(endInline) && isCollapsed
+ const isVoidBlock = endBlock && change.isVoid(endBlock) && isCollapsed
+ const isVoidInline = endInline && change.isVoid(endInline) && isCollapsed
if (isVoidBlock) {
editor.change(c => c.removeNodeByKey(endBlock.key))
@@ -243,13 +392,57 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onDragEnd(event, change, editor) {
+ function onDragEnd(event, change, next) {
debug('onDragEnd', { event })
-
+ isDragging = false
isDraggingInternally = null
+ return next()
+ }
+
+ /**
+ * On drag enter.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onDragEnter(event, change, next) {
+ debug('onDragEnter', { event })
+ return next()
+ }
+
+ /**
+ * On drag exit.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onDragExit(event, change, next) {
+ debug('onDragExit', { event })
+ return next()
+ }
+
+ /**
+ * On drag leave.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onDragLeave(event, change, next) {
+ debug('onDragLeave', { event })
+ return next()
}
/**
@@ -257,11 +450,39 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onDragOver(event, change, editor) {
+ function onDragOver(event, change, next) {
debug('onDragOver', { event })
+
+ // If the target is inside a void node, and only in this case,
+ // call `preventDefault` to signal that drops are allowed.
+ // When the target is editable, dropping is already allowed by
+ // default, and calling `preventDefault` hides the cursor.
+ const { editor } = change
+ const node = findNode(event.target, editor)
+ if (change.isVoid(node)) event.preventDefault()
+
+ // COMPAT: IE won't call onDrop on contentEditables unless the
+ // default dragOver is prevented:
+ // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/913982/
+ // (2018/07/11)
+ if (IS_IE) event.preventDefault()
+
+ // If a drag is already in progress, don't do this again.
+ if (!isDragging) {
+ isDragging = true
+
+ // COMPAT: IE will raise an `unspecified error` if dropEffect is
+ // set. (2018/07/11)
+ if (!IS_IE) {
+ event.nativeEvent.dataTransfer.dropEffect = 'move'
+ }
+ }
+
+ return next()
}
/**
@@ -269,20 +490,27 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onDragStart(event, change, editor) {
+ function onDragStart(event, change, next) {
debug('onDragStart', { event })
+ isDragging = true
isDraggingInternally = true
- const { value } = change
- const { document, schema } = value
- const node = findNode(event.target, value)
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { editor } = change
+ const { value } = editor
+ const { document } = value
+ const node = findNode(event.target, editor)
const ancestors = document.getAncestors(node.key)
const isVoid =
- node && (schema.isVoid(node) || ancestors.some(a => schema.isVoid(a)))
+ node && (change.isVoid(node) || ancestors.some(a => change.isVoid(a)))
const selectionIncludesNode = value.blocks.some(
block => block.key === node.key
)
@@ -302,17 +530,27 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onDrop(event, change, editor) {
+ function onDrop(event, change, next) {
+ const { editor, value } = change
+ if (editor.readOnly) return true
+
debug('onDrop', { event })
- const { value } = change
- const { document, selection, schema } = value
+ // Prevent default so the DOM's value isn't corrupted.
+ event.preventDefault()
+
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { document, selection } = value
const window = getWindow(event.target)
- let target = getEventRange(event, value)
- if (!target) return
+ let target = getEventRange(event, editor)
+ if (!target) return true
const transfer = getEventTransfer(event)
const { type, fragment, text } = transfer
@@ -341,7 +579,7 @@ function AfterPlugin() {
if (type == 'text' || type == 'html') {
const { anchor } = target
- let hasVoidParent = document.hasVoidParent(anchor.key, schema)
+ let hasVoidParent = document.hasVoidParent(anchor.key, editor)
if (hasVoidParent) {
let n = document.getNode(anchor.key)
@@ -349,7 +587,7 @@ function AfterPlugin() {
while (hasVoidParent) {
n = document.getNextText(n.key)
if (!n) break
- hasVoidParent = document.hasVoidParent(n.key, schema)
+ hasVoidParent = document.hasVoidParent(n.key, editor)
}
if (n) change.moveToStartOfNode(n)
@@ -373,7 +611,7 @@ function AfterPlugin() {
// DOM node, since that will make it go back to normal.
const focusNode = document.getNode(target.focus.key)
const el = findDOMNode(focusNode, window)
- if (!el) return
+ if (!el) return true
el.dispatchEvent(
new MouseEvent('mouseup', {
@@ -382,25 +620,68 @@ function AfterPlugin() {
cancelable: true,
})
)
+
+ return true
+ }
+
+ /**
+ * On focus.
+ *
+ * @param {Event} event
+ * @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
+ */
+
+ function onFocus(event, change, next) {
+ const { editor } = change
+ if (isCopying) return true
+ if (editor.readOnly) return true
+
+ const el = ReactDOM.findDOMNode(editor)
+
+ // Save the new `activeElement`.
+ const window = getWindow(event.target)
+ activeElement = window.document.activeElement
+
+ // COMPAT: If the editor has nested editable elements, the focus can go to
+ // those elements. In Firefox, this must be prevented because it results in
+ // issues with keyboard navigation. (2017/03/30)
+ if (IS_FIREFOX && event.target != el) {
+ el.focus()
+ return true
+ }
+
+ debug('onFocus', { event })
+ return next()
}
/**
* On input.
*
- * @param {Event} eventvent
+ * @param {Event} event
* @param {Change} change
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onInput(event, change, editor) {
+ function onInput(event, change, next) {
+ if (isComposing) return true
+ if (change.value.selection.isBlurred) return true
+
debug('onInput', { event })
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
const window = getWindow(event.target)
- const { value } = change
+ const { editor, value } = change
// Get the selection point.
const native = window.getSelection()
const { anchorNode } = native
- const point = findPoint(anchorNode, 0, value)
+ const point = findPoint(anchorNode, 0, editor)
if (!point) return
// Get the text node and leaf in question.
@@ -455,15 +736,51 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onKeyDown(event, change, editor) {
+ function onKeyDown(event, change, next) {
+ const { editor, value } = change
+ if (editor.readOnly) return true
+
+ // When composing, we need to prevent all hotkeys from executing while
+ // typing. However, certain characters also move the selection before
+ // we're able to handle it, so prevent their default behavior.
+ if (isComposing) {
+ if (Hotkeys.isCompose(event)) event.preventDefault()
+ return true
+ }
+
debug('onKeyDown', { event })
- const { value } = change
- const { document, selection, schema } = value
- const hasVoidParent = document.hasVoidParent(selection.start.path, schema)
+ // Certain hotkeys have native editing behaviors in `contenteditable`
+ // elements which will change the DOM and cause our value to be out of sync,
+ // so they need to always be prevented.
+ if (
+ !IS_IOS &&
+ (Hotkeys.isBold(event) ||
+ Hotkeys.isDeleteBackward(event) ||
+ Hotkeys.isDeleteForward(event) ||
+ Hotkeys.isDeleteLineBackward(event) ||
+ Hotkeys.isDeleteLineForward(event) ||
+ Hotkeys.isDeleteWordBackward(event) ||
+ Hotkeys.isDeleteWordForward(event) ||
+ Hotkeys.isItalic(event) ||
+ Hotkeys.isRedo(event) ||
+ Hotkeys.isSplitBlock(event) ||
+ Hotkeys.isTransposeCharacter(event) ||
+ Hotkeys.isUndo(event))
+ ) {
+ event.preventDefault()
+ }
+
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { document, selection } = value
+ const hasVoidParent = document.hasVoidParent(selection.start.path, editor)
// COMPAT: In iOS, some of these hotkeys are handled in the
// `onNativeBeforeInput` handler of the `
` component in order to
@@ -535,7 +852,7 @@ function AfterPlugin() {
if (Hotkeys.isMoveBackward(event)) {
const { previousText, startText } = value
const isPreviousInVoid =
- previousText && document.hasVoidParent(previousText.key, schema)
+ previousText && document.hasVoidParent(previousText.key, editor)
if (hasVoidParent || isPreviousInVoid || startText.text == '') {
event.preventDefault()
@@ -546,7 +863,7 @@ function AfterPlugin() {
if (Hotkeys.isMoveForward(event)) {
const { nextText, startText } = value
const isNextInVoid =
- nextText && document.hasVoidParent(nextText.key, schema)
+ nextText && document.hasVoidParent(nextText.key, editor)
if (hasVoidParent || isNextInVoid || startText.text == '') {
event.preventDefault()
@@ -557,7 +874,7 @@ function AfterPlugin() {
if (Hotkeys.isExtendBackward(event)) {
const { previousText, startText } = value
const isPreviousInVoid =
- previousText && document.hasVoidParent(previousText.key, schema)
+ previousText && document.hasVoidParent(previousText.key, editor)
if (hasVoidParent || isPreviousInVoid || startText.text == '') {
event.preventDefault()
@@ -568,13 +885,15 @@ function AfterPlugin() {
if (Hotkeys.isExtendForward(event)) {
const { nextText, startText } = value
const isNextInVoid =
- nextText && document.hasVoidParent(nextText.key, schema)
+ nextText && document.hasVoidParent(nextText.key, editor)
if (hasVoidParent || isNextInVoid || startText.text == '') {
event.preventDefault()
return change.moveFocusForward()
}
}
+
+ return true
}
/**
@@ -582,12 +901,23 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onPaste(event, change, editor) {
+ function onPaste(event, change, next) {
+ const { editor, value } = change
+ if (editor.readOnly) return true
+
debug('onPaste', { event })
+ // Prevent defaults so the DOM state isn't corrupted.
+ event.preventDefault()
+
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
const transfer = getEventTransfer(event)
const { type, fragment, text } = transfer
@@ -596,10 +926,9 @@ function AfterPlugin() {
}
if (type == 'text' || type == 'html') {
- if (!text) return
- const { value } = change
- const { document, selection, startBlock, schema } = value
- if (schema.isVoid(startBlock)) return
+ if (!text) return true
+ const { document, selection, startBlock } = value
+ if (change.isVoid(startBlock)) return true
const defaultBlock = startBlock
const defaultMarks = document.getInsertMarksAtRange(selection)
@@ -607,6 +936,8 @@ function AfterPlugin() {
.document
change.insertFragment(frag)
}
+
+ return true
}
/**
@@ -614,26 +945,39 @@ function AfterPlugin() {
*
* @param {Event} event
* @param {Change} change
- * @param {Editor} editor
+ * @param {Function} next
+ * @return {Boolean}
*/
- function onSelect(event, change, editor) {
+ function onSelect(event, change, next) {
+ if (isCopying) return true
+ if (isComposing) return true
+
+ const { editor, value } = change
+ if (editor.readOnly) return true
+
debug('onSelect', { event })
+ // Save the new `activeElement`.
const window = getWindow(event.target)
- const { value } = change
- const { document, schema } = value
+ activeElement = window.document.activeElement
+
+ // Delegate to the plugins stack.
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { document } = value
const native = window.getSelection()
// If there are no ranges, the editor was blurred natively.
if (!native.rangeCount) {
change.blur()
- return
+ return true
}
// Otherwise, determine the Slate selection from the native one.
- let range = findRange(native, value)
- if (!range) return
+ let range = findRange(native, editor)
+ if (!range) return true
const { anchor, focus } = range
const anchorText = document.getNode(anchor.key)
@@ -652,10 +996,10 @@ function AfterPlugin() {
// selection, go with `0`. (2017/09/07)
if (
anchorBlock &&
- !schema.isVoid(anchorBlock) &&
+ !change.isVoid(anchorBlock) &&
anchor.offset == 0 &&
focusBlock &&
- schema.isVoid(focusBlock) &&
+ change.isVoid(focusBlock) &&
focus.offset != 0
) {
range = range.setFocus(focus.setOffset(0))
@@ -666,22 +1010,22 @@ function AfterPlugin() {
// standardizes the behavior, since it's indistinguishable to the user.
if (
anchorInline &&
- !schema.isVoid(anchorInline) &&
+ !change.isVoid(anchorInline) &&
anchor.offset == anchorText.text.length
) {
const block = document.getClosestBlock(anchor.key)
- const next = block.getNextText(anchor.key)
- if (next) range = range.moveAnchorTo(next.key, 0)
+ const nextText = block.getNextText(anchor.key)
+ if (nextText) range = range.moveAnchorTo(nextText.key, 0)
}
if (
focusInline &&
- !schema.isVoid(focusInline) &&
+ !change.isVoid(focusInline) &&
focus.offset == focusText.text.length
) {
const block = document.getClosestBlock(focus.key)
- const next = block.getNextText(focus.key)
- if (next) range = range.moveFocusTo(next.key, 0)
+ const nextText = block.getNextText(focus.key)
+ if (nextText) range = range.moveFocusTo(nextText.key, 0)
}
let selection = document.createSelection(range)
@@ -692,83 +1036,7 @@ function AfterPlugin() {
selection = selection.set('marks', value.selection.marks)
change.select(selection)
- }
-
- /**
- * Render editor.
- *
- * @param {Object} props
- * @param {Editor} editor
- * @return {Object}
- */
-
- function renderEditor(props, editor) {
- const { handlers } = editor
- return (
-
- )
- }
-
- /**
- * Render node.
- *
- * @param {Object} props
- * @return {Element}
- */
-
- function renderNode(props) {
- const { attributes, children, node } = props
- if (node.object != 'block' && node.object != 'inline') return
- const Tag = node.object == 'block' ? 'div' : 'span'
- const style = { position: 'relative' }
- return (
-
- {children}
-
- )
- }
-
- /**
- * Render placeholder.
- *
- * @param {Object} props
- * @return {Element}
- */
-
- function renderPlaceholder(props) {
- const { editor, node } = props
- if (!editor.props.placeholder) return
- if (editor.state.isComposing) return
- if (node.object != 'block') return
- if (!Text.isTextList(node.nodes)) return
- if (node.text != '') return
- if (editor.value.document.getBlocks().size > 1) return
-
- const style = {
- pointerEvents: 'none',
- display: 'inline-block',
- width: '0',
- maxWidth: '100%',
- whiteSpace: 'nowrap',
- opacity: '0.333',
- }
-
- return (
-
- {editor.props.placeholder}
-
- )
+ return true
}
/**
@@ -781,19 +1049,22 @@ function AfterPlugin() {
onBeforeInput,
onBlur,
onClick,
+ onCompositionEnd,
+ onCompositionStart,
onCopy,
onCut,
onDragEnd,
+ onDragEnter,
+ onDragExit,
+ onDragLeave,
onDragOver,
onDragStart,
onDrop,
+ onFocus,
onInput,
onKeyDown,
onPaste,
onSelect,
- renderEditor,
- renderNode,
- renderPlaceholder,
}
}
@@ -803,4 +1074,4 @@ function AfterPlugin() {
* @type {Object}
*/
-export default AfterPlugin
+export default BrowserPlugin
diff --git a/packages/slate-react/src/plugins/props.js b/packages/slate-react/src/plugins/props.js
new file mode 100644
index 000000000..ad57dde93
--- /dev/null
+++ b/packages/slate-react/src/plugins/props.js
@@ -0,0 +1,46 @@
+import EVENT_HANDLERS from '../constants/event-handlers'
+
+/**
+ * Props that can be defined by plugins.
+ *
+ * @type {Array}
+ */
+
+const PROPS = [
+ ...EVENT_HANDLERS,
+ 'commands',
+ 'decorateNode',
+ 'queries',
+ 'renderEditor',
+ 'renderMark',
+ 'renderNode',
+ 'renderPlaceholder',
+ 'schema',
+]
+
+/**
+ * A plugin that is defined from the props on the `` component.
+ *
+ * @param {Object} props
+ * @return {Object}
+ */
+
+function PropsPlugin(props) {
+ const plugin = {}
+
+ for (const prop of PROPS) {
+ if (prop in props) {
+ plugin[prop] = props[prop]
+ }
+ }
+
+ return plugin
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default PropsPlugin
diff --git a/packages/slate-react/src/plugins/react.js b/packages/slate-react/src/plugins/react.js
new file mode 100644
index 000000000..440fc78d7
--- /dev/null
+++ b/packages/slate-react/src/plugins/react.js
@@ -0,0 +1,122 @@
+import React from 'react'
+import { Text } from 'slate'
+
+import Content from '../components/content'
+
+/**
+ * A plugin that adds the React-specific rendering logic to the editor.
+ *
+ * @return {Object}
+ */
+
+function ReactPlugin() {
+ /**
+ * Render editor.
+ *
+ * @param {Object} props
+ * @param {Editor} editor
+ * @param {Function} next
+ * @return {Object}
+ */
+
+ function renderEditor(props, editor, next) {
+ const children = (
+
+ )
+
+ const ret = next({ ...props, children }, editor)
+ return ret !== undefined ? ret : children
+ }
+
+ /**
+ * Render node.
+ *
+ * @param {Object} props
+ * @param {Editor} editor
+ * @param {Function} next
+ * @return {Element}
+ */
+
+ function renderNode(props, editor, next) {
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { attributes, children, node } = props
+ if (node.object != 'block' && node.object != 'inline') return null
+ const Tag = node.object == 'block' ? 'div' : 'span'
+ const style = { position: 'relative' }
+ return (
+
+ {children}
+
+ )
+ }
+
+ /**
+ * Render placeholder.
+ *
+ * @param {Object} props
+ * @param {Editor} editor
+ * @param {Function} next
+ * @return {Element}
+ */
+
+ function renderPlaceholder(props, editor, next) {
+ const ret = next()
+ if (ret !== undefined) return ret
+
+ const { node } = props
+ if (!editor.props.placeholder) return null
+ if (editor.state.isComposing) return null
+ if (node.object != 'block') return null
+ if (!Text.isTextList(node.nodes)) return null
+ if (node.text != '') return null
+ if (editor.value.document.getBlocks().size > 1) return null
+
+ const style = {
+ pointerEvents: 'none',
+ display: 'inline-block',
+ width: '0',
+ maxWidth: '100%',
+ whiteSpace: 'nowrap',
+ opacity: '0.333',
+ }
+
+ return (
+
+ {editor.props.placeholder}
+
+ )
+ }
+
+ /**
+ * Return the plugin.
+ *
+ * @type {Object}
+ */
+
+ return {
+ renderEditor,
+ renderNode,
+ renderPlaceholder,
+ }
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default ReactPlugin
diff --git a/packages/slate-react/src/utils/clone-fragment.js b/packages/slate-react/src/utils/clone-fragment.js
index 399f0a74e..f77d06d55 100644
--- a/packages/slate-react/src/utils/clone-fragment.js
+++ b/packages/slate-react/src/utils/clone-fragment.js
@@ -1,11 +1,12 @@
import Base64 from 'slate-base64-serializer'
import Plain from 'slate-plain-serializer'
-import { Value } from 'slate'
import TRANSFER_TYPES from '../constants/transfer-types'
-import getWindow from 'get-window'
import findDOMNode from './find-dom-node'
+import getWindow from 'get-window'
+import invariant from 'tiny-invariant'
import removeAllRanges from './remove-all-ranges'
import { IS_IE } from 'slate-dev-environment'
+import { Value } from 'slate'
import { ZERO_WIDTH_SELECTOR, ZERO_WIDTH_ATTRIBUTE } from './find-point'
const { FRAGMENT, HTML, TEXT } = TRANSFER_TYPES
@@ -14,22 +15,22 @@ const { FRAGMENT, HTML, TEXT } = TRANSFER_TYPES
* Prepares a Slate document fragment to be copied to the clipboard.
*
* @param {Event} event
- * @param {Value} value
- * @param {Document} [fragment]
+ * @param {Editor} editor
*/
-function cloneFragment(
- event,
- value,
- fragment = value.fragment,
- callback = () => undefined
-) {
+function cloneFragment(event, editor, callback = () => undefined) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `cloneFragment` utility takes an `editor` instead of a `value`.'
+ )
+
const window = getWindow(event.target)
const native = window.getSelection()
- const { schema } = value
- const { start, end } = value.selection
- const startVoid = value.document.getClosestVoid(start.key, schema)
- const endVoid = value.document.getClosestVoid(end.key, schema)
+ const { value } = editor
+ const { document, fragment, selection } = value
+ const { start, end } = selection
+ const startVoid = document.getClosestVoid(start.key, editor)
+ const endVoid = document.getClosestVoid(end.key, editor)
// If the selection is collapsed, and it isn't inside a void node, abort.
if (native.isCollapsed && !startVoid) return
@@ -118,16 +119,16 @@ function cloneFragment(
// COMPAT: For browser that don't support the Clipboard API's setData method,
// we must rely on the browser to natively copy what's selected.
// So we add the div (containing our content) to the DOM, and select it.
- const editor = event.target.closest('[data-slate-editor]')
+ const editorEl = event.target.closest('[data-slate-editor]')
div.setAttribute('contenteditable', true)
div.style.position = 'absolute'
div.style.left = '-9999px'
- editor.appendChild(div)
+ editorEl.appendChild(div)
native.selectAllChildren(div)
// Revert to the previous selection right after copying.
window.requestAnimationFrame(() => {
- editor.removeChild(div)
+ editorEl.removeChild(div)
removeAllRanges(native)
native.addRange(range)
callback()
diff --git a/packages/slate-react/src/utils/find-node.js b/packages/slate-react/src/utils/find-node.js
index 65c860db5..3e64d3472 100644
--- a/packages/slate-react/src/utils/find-node.js
+++ b/packages/slate-react/src/utils/find-node.js
@@ -1,19 +1,29 @@
+import invariant from 'tiny-invariant'
+import { Value } from 'slate'
+
/**
* Find a Slate node from a DOM `element`.
*
* @param {Element} element
- * @param {Value} value
+ * @param {Editor} editor
* @return {Node|Null}
*/
-function findNode(element, value) {
+function findNode(element, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `findNode` utility takes an `editor` instead of a `value`.'
+ )
+
const closest = element.closest('[data-key]')
if (!closest) return null
const key = closest.getAttribute('data-key')
if (!key) return null
- const node = value.document.getNode(key)
+ const { value } = editor
+ const { document } = value
+ const node = document.getNode(key)
return node || null
}
diff --git a/packages/slate-react/src/utils/find-point.js b/packages/slate-react/src/utils/find-point.js
index 5439ddd32..4322c2aea 100644
--- a/packages/slate-react/src/utils/find-point.js
+++ b/packages/slate-react/src/utils/find-point.js
@@ -1,4 +1,6 @@
import getWindow from 'get-window'
+import invariant from 'tiny-invariant'
+import { Value } from 'slate'
import OffsetKey from './offset-key'
@@ -20,11 +22,16 @@ const VOID_SELECTOR = '[data-slate-void]'
*
* @param {Element} nativeNode
* @param {Number} nativeOffset
- * @param {Value} value
+ * @param {Editor} editor
* @return {Point}
*/
-function findPoint(nativeNode, nativeOffset, value) {
+function findPoint(nativeNode, nativeOffset, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `findPoint` utility takes an `editor` instead of a `value`.'
+ )
+
const { node: nearestNode, offset: nearestOffset } = normalizeNodeAndOffset(
nativeNode,
nativeOffset
@@ -76,6 +83,7 @@ function findPoint(nativeNode, nativeOffset, value) {
// COMPAT: If someone is clicking from one Slate editor into another, the
// select event fires twice, once for the old editor's `element` first, and
// then afterwards for the correct `element`. (2017/03/03)
+ const { value } = editor
if (!value.document.hasDescendant(key)) return null
const point = value.document.createPoint({ key, offset })
diff --git a/packages/slate-react/src/utils/find-range.js b/packages/slate-react/src/utils/find-range.js
index 7de935a4a..b160f7506 100644
--- a/packages/slate-react/src/utils/find-range.js
+++ b/packages/slate-react/src/utils/find-range.js
@@ -1,5 +1,7 @@
import getWindow from 'get-window'
+import invariant from 'tiny-invariant'
import { IS_IE, IS_EDGE } from 'slate-dev-environment'
+import { Value } from 'slate'
import findPoint from './find-point'
import findDOMPoint from './find-dom-point'
@@ -8,11 +10,16 @@ import findDOMPoint from './find-dom-point'
* Find a Slate range from a DOM `native` selection.
*
* @param {Selection} native
- * @param {Value} value
+ * @param {Editor} editor
* @return {Range}
*/
-function findRange(native, value) {
+function findRange(native, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `findNode` utility takes an `editor` instead of a `value`.'
+ )
+
const el = native.anchorNode || native.startContainer
if (!el) return null
@@ -39,8 +46,9 @@ function findRange(native, value) {
focusOffset,
isCollapsed,
} = native
- const anchor = findPoint(anchorNode, anchorOffset, value)
- const focus = isCollapsed ? anchor : findPoint(focusNode, focusOffset, value)
+ const { value } = editor
+ const anchor = findPoint(anchorNode, anchorOffset, editor)
+ const focus = isCollapsed ? anchor : findPoint(focusNode, focusOffset, editor)
if (!anchor || !focus) return null
// COMPAT: ??? The Edge browser seems to have a case where if you select the
diff --git a/packages/slate-react/src/utils/get-event-range.js b/packages/slate-react/src/utils/get-event-range.js
index 690c99a99..74e6ebec0 100644
--- a/packages/slate-react/src/utils/get-event-range.js
+++ b/packages/slate-react/src/utils/get-event-range.js
@@ -1,4 +1,6 @@
import getWindow from 'get-window'
+import invariant from 'tiny-invariant'
+import { Value } from 'slate'
import findNode from './find-node'
import findRange from './find-range'
@@ -7,11 +9,16 @@ import findRange from './find-range'
* Get the target range from a DOM `event`.
*
* @param {Event} event
- * @param {Value} value
+ * @param {Editor} editor
* @return {Range}
*/
-function getEventRange(event, value) {
+function getEventRange(event, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `findNode` utility takes an `editor` instead of a `value`.'
+ )
+
if (event.nativeEvent) {
event = event.nativeEvent
}
@@ -19,14 +26,15 @@ function getEventRange(event, value) {
const { x, y, target } = event
if (x == null || y == null) return null
- const { document, schema } = value
- const node = findNode(target, value)
+ const { value } = editor
+ const { document } = value
+ const node = findNode(target, editor)
if (!node) return null
// If the drop target is inside a void node, move it into either the next or
// previous node, depending on which side the `x` and `y` coordinates are
// closest to.
- if (schema.isVoid(node)) {
+ if (editor.query('isVoid', node)) {
const rect = target.getBoundingClientRect()
const isPrevious =
node.object == 'inline'
@@ -75,7 +83,7 @@ function getEventRange(event, value) {
}
// Resolve a Slate range from the DOM range.
- const range = findRange(native, value)
+ const range = findRange(native, editor)
if (!range) return null
return range
diff --git a/packages/slate-react/src/utils/noop.js b/packages/slate-react/src/utils/noop.js
deleted file mode 100644
index ba75f6129..000000000
--- a/packages/slate-react/src/utils/noop.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Noop.
- *
- * @return {Void}
- */
-
-function noop() {}
-
-/**
- * Export.
- *
- * @type {Function}
- */
-
-export default noop
diff --git a/packages/slate-react/test/index.js b/packages/slate-react/test/index.js
index 026ee1dc5..8c4e22013 100644
--- a/packages/slate-react/test/index.js
+++ b/packages/slate-react/test/index.js
@@ -1,27 +1,12 @@
-import AfterPlugin from '../src/plugins/after'
import assert from 'assert'
-import BeforePlugin from '../src/plugins/before'
import clean from './helpers/clean'
import React from 'react'
import ReactDOM from 'react-dom/server'
-import Simulator from 'slate-simulator'
import { Editor } from 'slate-react'
import { fixtures } from 'slate-dev-test-utils'
import { JSDOM } from 'jsdom'
describe('slate-react', () => {
- fixtures.skip(__dirname, 'plugins', ({ module }) => {
- const { input, output, props = {} } = module
- const fn = module.default
- const plugins = [BeforePlugin(props), AfterPlugin(props)]
- const simulator = new Simulator({ plugins, value: input })
- fn(simulator)
-
- const actual = simulator.value.toJSON({ preserveSelection: true })
- const expected = output.toJSON({ preserveSelection: true })
- assert.deepEqual(actual, expected)
- })
-
fixtures(__dirname, 'rendering/fixtures', ({ module }) => {
const { value, output, props } = module
const p = {
diff --git a/packages/slate-react/test/rendering/fixtures/custom-block-blurred.js b/packages/slate-react/test/rendering/fixtures/custom-block-blurred.js
index 184ca17ed..0c579114e 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-block-blurred.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-block-blurred.js
@@ -33,18 +33,28 @@ export const value = (
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+
)
- .change()
- .blur().value
export const output = `
diff --git a/packages/slate-react/test/rendering/fixtures/custom-block-focused.js b/packages/slate-react/test/rendering/fixtures/custom-block-focused.js
index 43e42e87f..7ff57a4a9 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-block-focused.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-block-focused.js
@@ -33,13 +33,21 @@ export const value = (
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
)
diff --git a/packages/slate-react/test/rendering/fixtures/custom-block-selected.js b/packages/slate-react/test/rendering/fixtures/custom-block-selected.js
index 75057b6bc..34fba60fc 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-block-selected.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-block-selected.js
@@ -33,13 +33,21 @@ export const value = (
-
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
)
diff --git a/packages/slate-react/test/rendering/fixtures/custom-block-void.js b/packages/slate-react/test/rendering/fixtures/custom-block-void.js
index 0d999437b..283d3b81d 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-block-void.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-block-void.js
@@ -31,7 +31,9 @@ export const props = {
export const value = (
-
+
+
+
)
diff --git a/packages/slate-react/test/rendering/fixtures/custom-inline-multiple.js b/packages/slate-react/test/rendering/fixtures/custom-inline-multiple.js
index 90b8d34a1..574bf5933 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-inline-multiple.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-inline-multiple.js
@@ -26,9 +26,13 @@ export const value = (
+
word
+
word
+
word
+
diff --git a/packages/slate-react/test/rendering/fixtures/custom-inline-void.js b/packages/slate-react/test/rendering/fixtures/custom-inline-void.js
index 82bf9aa33..9bddf6ec4 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-inline-void.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-inline-void.js
@@ -29,7 +29,11 @@ export const value = (
-
+
+
+
+
+
diff --git a/packages/slate-react/test/rendering/fixtures/custom-inline.js b/packages/slate-react/test/rendering/fixtures/custom-inline.js
index 987844b88..dd8cefc30 100644
--- a/packages/slate-react/test/rendering/fixtures/custom-inline.js
+++ b/packages/slate-react/test/rendering/fixtures/custom-inline.js
@@ -26,7 +26,9 @@ export const value = (
+
word
+
diff --git a/packages/slate-react/test/rendering/fixtures/default-block-with-inline.js b/packages/slate-react/test/rendering/fixtures/default-block-with-inline.js
index 8ad1cd7e4..f227b4d79 100644
--- a/packages/slate-react/test/rendering/fixtures/default-block-with-inline.js
+++ b/packages/slate-react/test/rendering/fixtures/default-block-with-inline.js
@@ -8,7 +8,9 @@ export const value = (
+
word
+
diff --git a/packages/slate-react/test/rendering/fixtures/empty-block.js b/packages/slate-react/test/rendering/fixtures/empty-block.js
index 162fabc31..a5a229356 100644
--- a/packages/slate-react/test/rendering/fixtures/empty-block.js
+++ b/packages/slate-react/test/rendering/fixtures/empty-block.js
@@ -7,7 +7,9 @@ export const props = {}
export const value = (
-
+
+
+
)
diff --git a/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js b/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
index dad2dcbad..14c86a5c2 100644
--- a/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
+++ b/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
@@ -32,7 +32,9 @@ export const props = {
export const value = (
-
+
+
+
)
diff --git a/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js b/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
index 624b380a3..469fb3723 100644
--- a/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
+++ b/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
@@ -30,7 +30,9 @@ export const value = (
-
+
+
+
diff --git a/packages/slate-simulator/Changelog.md b/packages/slate-simulator/Changelog.md
deleted file mode 100644
index 11e4e4014..000000000
--- a/packages/slate-simulator/Changelog.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Changelog
-
-This document maintains a list of changes to the `slate-simulator` package with each new version. Until `1.0.0` is released, breaking changes will be added as minor version bumps, and smaller changes won't be accounted for since the library is moving quickly.
-
----
-
-### `0.4.0` — October 27, 2017
-
-###### BREAKING
-
-**Remove all previously deprecated code paths.** This helps to reduce some of the complexity in Slate by not having to handle these code paths anymore. And it helps to reduce file size. When upgrading, it's _highly_ recommended that you upgrade to the previous version first and ensure there are no deprecation warnings being logged, then upgrade to this version.
-
----
-
-### `0.3.0` — October 27, 2017
-
-###### DEPRECATED
-
-**The `props.state` prop has been renamed to `props.value`.** This is to stay in line with `slate-react@0.9.0` where the same change was made to the `
`.
-
-**The `simulator.state` property is now `simulator.value`** This is to stay in line with `slate@0.29.0` where the same change as made to the `Change` objects.
-
----
-
-### `0.2.0` — October 25, 2017
-
-###### BREAKING
-
-**Updated to work with `slate@0.28.0`.** Along with the new Schema, the `Stack` which is used internally by the simulator has changed slightly.
-
----
-
-### `0.1.0` — September 17, 2017
-
-:tada:
diff --git a/packages/slate-simulator/Readme.md b/packages/slate-simulator/Readme.md
deleted file mode 100644
index 632bd088e..000000000
--- a/packages/slate-simulator/Readme.md
+++ /dev/null
@@ -1 +0,0 @@
-This package contains a simulator for testing Slate editors and plugins.
diff --git a/packages/slate-simulator/package.json b/packages/slate-simulator/package.json
deleted file mode 100644
index 37e22cf64..000000000
--- a/packages/slate-simulator/package.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "slate-simulator",
- "description": "A simulator for testing Slate editors and plugins.",
- "version": "0.4.67",
- "license": "MIT",
- "repository": "git://github.com/ianstormtaylor/slate.git",
- "main": "lib/slate-simulator.js",
- "module": "lib/slate-simulator.es.js",
- "umd": "dist/slate-simulator.js",
- "umdMin": "dist/slate-simulator.min.js",
- "files": [
- "dist/",
- "lib/"
- ],
- "peerDependencies": {
- "slate": ">=0.32.0"
- },
- "devDependencies": {
- "slate": "^0.41.3"
- },
- "scripts": {
- "clean": "rm -rf ./dist ./lib ./node_modules"
- },
- "umdGlobals": {
- "slate": "Slate"
- },
- "keywords": [
- "ci",
- "editor",
- "simulate",
- "simulator",
- "spec",
- "slate",
- "test",
- "testing",
- "unit"
- ]
-}
diff --git a/packages/slate-simulator/src/index.js b/packages/slate-simulator/src/index.js
deleted file mode 100644
index f1e1242fd..000000000
--- a/packages/slate-simulator/src/index.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import { Stack } from 'slate'
-
-/**
- * Event handlers that can be simulated.
- *
- * @type {Array}
- */
-
-const EVENT_HANDLERS = [
- 'onBeforeInput',
- 'onBlur',
- 'onCopy',
- 'onCut',
- 'onDrop',
- 'onFocus',
- 'onKeyDown',
- 'onKeyUp',
- 'onPaste',
- 'onSelect',
-]
-
-/**
- * Simulator.
- *
- * @type {Simulator}
- */
-
-class Simulator {
- /**
- * Create a new `Simulator` with `plugins` and an initial `value`.
- *
- * @param {Object} attrs
- */
-
- constructor(props) {
- const { plugins, value } = props
- const stack = new Stack({ plugins })
- this.props = props
- this.stack = stack
- this.value = value
- }
-}
-
-/**
- * Generate the event simulators.
- */
-
-EVENT_HANDLERS.forEach(handler => {
- const method = getMethodName(handler)
-
- Simulator.prototype[method] = function(e) {
- if (e == null) e = {}
-
- const { stack, value } = this
- const editor = createEditor(this)
- const event = createEvent(e)
- const change = value.change()
-
- stack.run(handler, event, change, editor)
- stack.run('onChange', change, editor)
-
- this.value = change.value
- return this
- }
-})
-
-/**
- * Get the method name from a `handler` name.
- *
- * @param {String} handler
- * @return {String}
- */
-
-function getMethodName(handler) {
- return handler.charAt(2).toLowerCase() + handler.slice(3)
-}
-
-/**
- * Create a fake editor from a `stack` and `value`.
- *
- * @param {Stack} stack
- * @param {Value} value
- */
-
-function createEditor({ stack, value, props }) {
- const editor = {
- getSchema: () => stack.schema,
- getState: () => value,
- props: {
- autoCorrect: true,
- autoFocus: false,
- onChange: () => {},
- readOnly: false,
- spellCheck: true,
- ...props,
- },
- }
-
- return editor
-}
-
-/**
- * Create a fake event with `attributes`.
- *
- * @param {Object} attributes
- * @return {Object}
- */
-
-function createEvent(attributes) {
- const event = {
- preventDefault: () => (event.isDefaultPrevented = true),
- stopPropagation: () => (event.isPropagationStopped = true),
- isDefaultPrevented: false,
- isPropagationStopped: false,
- ...attributes,
- }
-
- return event
-}
-
-/**
- * Export.
- *
- * @type {Object}
- */
-
-export default Simulator
diff --git a/packages/slate-simulator/test/index.js b/packages/slate-simulator/test/index.js
deleted file mode 100644
index e69de29bb..000000000
diff --git a/packages/slate/Changelog.md b/packages/slate/Changelog.md
index 10ed1b89a..c683691ec 100644
--- a/packages/slate/Changelog.md
+++ b/packages/slate/Changelog.md
@@ -4,6 +4,192 @@ A list of changes to the `slate` package with each new version. Until `1.0.0` is
---
+### `0.42.0` — October 9, 2018
+
+###### NEW
+
+**Introducing the `Editor` controller.** Previously there was a vague `editor` concept, that was the React component itself. This was helpful, but because it was tightly coupled to React and the browser, it didn't lend itself to non-browser use cases well. This meant that the line between "model" and "controller/view" was blurred, and some concepts lived in both places at once, in inconsistent ways.
+
+A new `Editor` controller now makes this relationship clear. It borrows many of its behaviors from the React `` component. And the component actually just instantiates its own plain JavaScript `Editor` under the covers to delegate the work to.
+
+This new concept powers a lot of the thinking in this new version, unlocking a lot of changes that bring a clearer separation of responsibilities to Slate. It allows us to create editors in any environment, which makes server-side use cases easier, brings parity to testing, and even opens us up to supporting other view layers like React Native or Vue.js in the future.
+
+It has a familiar API, based on the existing `editor` concept:
+
+```js
+const editor = new Editor({ plugins, value, onChange })
+
+editor.change(change => {
+ ...
+})
+```
+
+However it also introduces imperative methods to make testing easier:
+
+```js
+editor.run('renderNode', props)
+
+editor.event('onKeyDown', event)
+
+editor.command('addMark', 'bold')
+
+editor.query('isVoid', node)
+```
+
+I'm very excited about it, so I hope you like it!
+
+**Introducing the "commands" concept.** Previously, "change methods" were treated in a first-class way, but plugins had no easy way to add their own change methods that were reusable elsewhere. And they had no way to override the built-in logic for certain commands, for example `splitBlock` or `insertText`. However, now this is all customizable by plugins, with the core Slate plugin providing all of the previous default commands.
+
+```js
+const plugin = {
+ commands: {
+ wrapQuote(change) {
+ change.wrapBlock('quote')
+ },
+ },
+}
+```
+
+Those commands are then available directly on the `change` objects, which are now editor-specific:
+
+```js
+change.wrapQuote()
+```
+
+This allows you to define all of your commands in a single, easily-testable place. And then "behavioral" plugins can simply take command names as options, so that you have full control over the logic they trigger.
+
+**Introducing the "queries" concept.** Similarly to the commands, queries allow plugins to define specific behaviors that the editor can be queried for in a reusable way, to be used when rendering buttons, or deciding on command behaviors, etc.
+
+For example, you might define an `getActiveList` query:
+
+```js
+const plugin = {
+ queries: {
+ getActiveList(value) {},
+ },
+}
+```
+
+And then be able to re-use that logic easily in different places in your codebase, or pass in the query name to a plugin that can use your custom logic itself:
+
+```js
+const { value } = change
+const list = change.getActiveList(value)
+
+if (list) {
+ ...
+} else {
+ ...
+}
+```
+
+Taken together, commands and queries offer a better way for plugins to manage their inter-dependencies. They can take in command or query names as options to change their behaviors, or they can export new commands and queries that you can reuse in your codebase.
+
+**The middleware stack is now deferrable.** With the introduction of the `Editor` controller, the middleware stack in Slate has also been upgraded. Each middleware now receives a `next` function (similar to Express or Koa) that allows you to choose whether to iterating the stack or not.
+
+```js
+// Previously, you'd return `undefined` to continue.
+function onKeyDown(event, change, editor) {
+ if (event.key !== 'Enter') return
+ ...
+}
+
+// Now, you call `next()` to continue...
+function onKeyDown(event, change, next) {
+ if (event.key !== 'Enter') return next()
+ ...
+}
+```
+
+While that may seem inconvenient, it opens up an entire new behavior, which is deferring to the plugins later in the stack to see if they "handle" a specific case, and if not, handling it yourself:
+
+```js
+function onKeyDown(event, change, next) {
+ if (event.key === 'Enter') {
+ const handled = next()
+ if (handled) return handled
+
+ // Otherwise, handle `Enter` yourself...
+ }
+}
+```
+
+This is how all of the core logic in `slate-react` is now implemented, eliminating the need for a "before" and an "after" plugin that duplicate logic.
+
+Under the covers, the `schema`, `commands` and `queries` concept are all implemented as plugins that attach varying middleware as well. For example, commands are processed using the `onCommand` middleware under the covers:
+
+```js
+const plugin = {
+ onCommand(command, change, next) {
+ ...
+ }
+}
+```
+
+This allows you to actually listen in to all commands, and override individual behaviors if you choose to do so, without having to override the command itself. This is a very advanced feature, which most people won't need, but it shows the flexibility provided by migrating all of the previously custom internal logic to be based on the new middleware stack.
+
+**Plugins can now be defined in nested arrays.** This is a small addition, but it means that you no longer need to differentiate between individual plugins and multiple plugins in an array. This allows plugins to be more easily composed up from multiple other plugins themselves, without the end user having to change how they use them. Small, but encourages reuse just a little bit more.
+
+###### DEPRECATED
+
+**The `slate-simulator` is deprecated.** Previously this was used as a pseudo-controller for testing purposes. However, now with the new `Editor` controller as a first-class concept, everything the simulator could do can now be done directly in the library. This should make testing in non-browser environments much easier to do.
+
+###### BREAKING
+
+**The `Value` object is no longer tied to changes.** Previously, you could create a new `Change` by calling `value.change()` and retrieve a new value. With the re-architecture to properly decouple the schema, commands, queries and plugins from the core Slate data models, this is no longer possible. Instead, changes are always created via an `Editor` instance, where those concepts live.
+
+```js
+// Instead of...
+const { value } = this.state
+const change = value.change()
+...
+this.onChange(change)
+
+// You now would do...
+this.editor.change(change => {
+ const { value } = change
+ ...
+})
+```
+
+Sometimes this means you will need to store the React `ref` of the `editor` to be able to access its `editor.change` method in your React components.
+
+**Remove the `Stack` "model", in favor of the new `Editor`.** Previously there was a pseudo-model called the `Stack` that was very low level, and not really a model. This concept has now been rolled into the new `Editor` controller, which can be used in any environment because it's just plain JavaScript. There was almost no need to directly use a `Stack` instance previously, so this change shouldn't affect almost anyone.
+
+**Remove the `Schema` "model", in favor of the new `Editor`.** Previously there was another pseudo-model called the `Schema`, that was used to contain validation logic. All of the same validation features are still available, but the old `Schema` model is now rolled into the `Editor` controller as well, in the form of an internal `SchemaPlugin` that isn't exposed.
+
+**Remove the `schema.isVoid` and `schema.isAtomic` in favor of queries.** Previously these two methods were used to query the schema about the behavior of a specific `node` or `decoration`. Now these same queries as possible using the "queries" concept, and are available directly on the `change` object:
+
+```js
+if (change.isVoid(node)) {
+ ...
+}
+```
+
+**The middleware stack must now be explicitly continued, using `next`.** Previously returning `undefined` from a middleware would (usually) continue the stack onto the next middleware. Now, with middleware taking a `next` function argument you must explicitly decide to continue the stack by call `next()` yourself.
+
+**Remove the `History` model, in favor of commands.** Previously there was a `History` model that stored the undo/redo stacks, and managing saving new operations to those stacks. All of this logic has been folded into the new "commands" concept, and the undo/redo stacks now live in `value.data`. This has the benefit of allowing the history behavior to be completely overridable by userland plugins, which was not an easy feat to manage before.
+
+**Values can no longer be normalized on creation.** With the decoupling of the data model and the plugin layer, the schema rules are no longer available inside the `Value` model. This means that you can no longer receive a "normalized" value without having access to the `Editor` and its plugins.
+
+```js
+// While previously you could attach a `schema` to a value...
+const normalized = Value.create({ ..., schema })
+
+// Now you'd need to do that with the `editor`...
+const value = Value.create({ ... })
+const editor = new Editor({ value, plugins: [{ schema }] })
+const normalized = editor.value
+```
+
+While this seems inconvenient, it makes the boundaries in the API much more clear, and keeps the immutable and mutable concepts separated. This specific code sample gets longer, but the complexities elsewhere in the library are removed.
+
+**The `Change` class is no longer exported.** Changes are now editor-specific, so exporting the `Change` class no longer makes sense. Instead, you can use the `editor.change()` API to receive a new change object with the commands and queries specific to your editor's plugins.
+
+**The `getClosestVoid`, `getDecorations` and `hasVoidParent` method now take an `editor`.** Previously these `Node` methods took a `schema` argument, but this has been replaced with the new `editor` controller instead now that the `Schema` model has been removed.
+
+---
+
### `0.41.0` — September 21, 2018
###### DEPRECATED
@@ -537,9 +723,9 @@ This is just an attempt to make dealing with normalization errors slightly more
###### BREAKING
-**Operation objects in Slate are now immutable records.** Previously they were native, mutable Javascript objects. Now, there's a new immutable `Operation` model in Slate, ensuring that all of the data inside `Value` objects are immutable. And it allows for easy serialization of operations using `operation.toJSON()` for when sending them between editors. This should not affect most users, unless you are relying on changing the values of the low-level Slate operations (simply reading them is fine).
+**Operation objects in Slate are now immutable records.** Previously they were native, mutable JavaScript objects. Now, there's a new immutable `Operation` model in Slate, ensuring that all of the data inside `Value` objects are immutable. And it allows for easy serialization of operations using `operation.toJSON()` for when sending them between editors. This should not affect most users, unless you are relying on changing the values of the low-level Slate operations (simply reading them is fine).
-**Operation lists in Slate are now immutable lists.** Previously they were native, mutable Javascript arrays. Now, to keep consistent with other immutable uses, they are immutable lists. This should not affect most users.
+**Operation lists in Slate are now immutable lists.** Previously they were native, mutable JavaScript arrays. Now, to keep consistent with other immutable uses, they are immutable lists. This should not affect most users.
---
@@ -873,7 +1059,7 @@ function onKeyDown(e, data, change) {
###### BREAKING
-**Void nodes are renderered implicitly again!** Previously Slate had required that you wrap void node renderers yourself with the exposed `` wrapping component. This was to allow for selection styling, but a change was made to make selection styling able to handled in Javascript. Now the `` wrapper will be implicitly rendered by Slate, so you do not need to worry about it, and "voidness" only needs to toggled in one place, the `isVoid: true` property of a node.
+**Void nodes are renderered implicitly again!** Previously Slate had required that you wrap void node renderers yourself with the exposed `` wrapping component. This was to allow for selection styling, but a change was made to make selection styling able to handled in JavaScript. Now the `` wrapper will be implicitly rendered by Slate, so you do not need to worry about it, and "voidness" only needs to toggled in one place, the `isVoid: true` property of a node.
---
@@ -919,7 +1105,7 @@ function onKeyDown(e, data, change) {
###### BREAKING
-**Void components are no longer rendered implicity!** Previously, Slate would automatically wrap any node with `isVoid: true` in a `` component. But doing this prevented you from customizing the wrapper, like adding a `className` or `style` property. So you **must now render the wrapper yourself**, and it has been exported as `Slate.Void`. This, combined with a small change to the `` component's structure allows the "selected" state of void nodes to be rendered purely with CSS based on the `:focus` property of a `` element, which previously [had to be handled in Javascript](https://github.com/ianstormtaylor/slate/commit/31782cb11a272466b6b9f1e4d6cc0c698504d97f). This allows us to streamline selection-handling logic, improving performance and reducing complexity.
+**Void components are no longer rendered implicity!** Previously, Slate would automatically wrap any node with `isVoid: true` in a `` component. But doing this prevented you from customizing the wrapper, like adding a `className` or `style` property. So you **must now render the wrapper yourself**, and it has been exported as `Slate.Void`. This, combined with a small change to the `` component's structure allows the "selected" state of void nodes to be rendered purely with CSS based on the `:focus` property of a `` element, which previously [had to be handled in JavaScript](https://github.com/ianstormtaylor/slate/commit/31782cb11a272466b6b9f1e4d6cc0c698504d97f). This allows us to streamline selection-handling logic, improving performance and reducing complexity.
**`data-offset-key` is now `-` instead of `:-`.** This shouldn't actually affect anyone, unless you were specifically relying on that attribute in the DOM. This change greatly reduces the number of re-renders needed, since previously any additional characters would cause a cascading change in the `` and `` offsets of latter text ranges.
diff --git a/packages/slate/package.json b/packages/slate/package.json
index 290a6e7d6..9072a2ee1 100644
--- a/packages/slate/package.json
+++ b/packages/slate/package.json
@@ -18,7 +18,8 @@
"esrever": "^0.2.0",
"is-plain-object": "^2.0.4",
"lodash": "^4.17.4",
- "slate-dev-warning": "^0.0.1",
+ "tiny-invariant": "^1.0.1",
+ "tiny-warning": "^0.0.3",
"type-of": "^2.0.1"
},
"peerDependencies": {
diff --git a/packages/slate/src/changes/index.js b/packages/slate/src/changes/index.js
deleted file mode 100644
index a399c645b..000000000
--- a/packages/slate/src/changes/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import AtCurrentRange from './at-current-range'
-import AtRange from './at-range'
-import ByPath from './by-path'
-import OnHistory from './on-history'
-import OnSelection from './on-selection'
-import OnValue from './on-value'
-
-/**
- * Export.
- *
- * @type {Object}
- */
-
-export default {
- ...AtCurrentRange,
- ...AtRange,
- ...ByPath,
- ...OnHistory,
- ...OnSelection,
- ...OnValue,
-}
diff --git a/packages/slate/src/changes/on-history.js b/packages/slate/src/changes/on-history.js
deleted file mode 100644
index 709c6d9d0..000000000
--- a/packages/slate/src/changes/on-history.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import omit from 'lodash/omit'
-
-/**
- * Changes.
- *
- * @type {Object}
- */
-
-const Changes = {}
-
-/**
- * Redo to the next value in the history.
- *
- * @param {Change} change
- */
-
-Changes.redo = change => {
- let { value } = change
- let { history } = value
- if (!history) return
-
- let { undos, redos } = history
- const next = redos.peek()
- if (!next) return
-
- // Shift the next value into the undo stack.
- redos = redos.pop()
- undos = undos.push(next)
-
- // Replay the next operations.
- next.forEach(op => {
- const { type, properties } = op
-
- // When the operation mutates the selection, omit its `isFocused` value to
- // prevent the editor focus from changing during redoing.
- if (type == 'set_selection') {
- op = op.set('properties', omit(properties, 'isFocused'))
- }
-
- change.withoutSaving(() => {
- change.applyOperation(op)
- })
- })
-
- // Update the history.
- value = change.value
- history = history.set('undos', undos).set('redos', redos)
- value = value.set('history', history)
- change.value = value
-}
-
-/**
- * Undo the previous operations in the history.
- *
- * @param {Change} change
- */
-
-Changes.undo = change => {
- let { value } = change
- let { history } = value
- if (!history) return
-
- let { undos, redos } = history
- const previous = undos.peek()
- if (!previous) return
-
- // Shift the previous operations into the redo stack.
- undos = undos.pop()
- redos = redos.push(previous)
-
- // Replay the inverse of the previous operations.
- previous
- .slice()
- .reverse()
- .map(op => op.invert())
- .forEach(inverse => {
- const { type, properties } = inverse
-
- // When the operation mutates the selection, omit its `isFocused` value to
- // prevent the editor focus from changing during undoing.
- if (type == 'set_selection') {
- inverse = inverse.set('properties', omit(properties, 'isFocused'))
- }
-
- change.withoutSaving(() => {
- change.applyOperation(inverse)
- })
- })
-
- // Update the history.
- value = change.value
- history = history.set('undos', undos).set('redos', redos)
- value = value.set('history', history)
- change.value = value
-}
-
-/**
- * Export.
- *
- * @type {Object}
- */
-
-export default Changes
diff --git a/packages/slate/src/changes/at-current-range.js b/packages/slate/src/commands/at-current-range.js
similarity index 92%
rename from packages/slate/src/changes/at-current-range.js
rename to packages/slate/src/commands/at-current-range.js
index ad50e2925..983c7ffee 100644
--- a/packages/slate/src/changes/at-current-range.js
+++ b/packages/slate/src/commands/at-current-range.js
@@ -3,12 +3,12 @@ import Inline from '../models/inline'
import Mark from '../models/mark'
/**
- * Changes.
+ * Commands.
*
* @type {Object}
*/
-const Changes = {}
+const Commands = {}
/**
* Mix in the changes that pass through to their at-range equivalents because
@@ -34,7 +34,7 @@ const PROXY_TRANSFORMS = [
]
PROXY_TRANSFORMS.forEach(method => {
- Changes[method] = (change, ...args) => {
+ Commands[method] = (change, ...args) => {
const { value } = change
const { selection } = value
const methodAtRange = `${method}AtRange`
@@ -55,7 +55,7 @@ PROXY_TRANSFORMS.forEach(method => {
* @param {Mark} mark
*/
-Changes.addMark = (change, mark) => {
+Commands.addMark = (change, mark) => {
mark = Mark.create(mark)
const { value } = change
const { document, selection } = value
@@ -80,7 +80,7 @@ Changes.addMark = (change, mark) => {
* @param {Mark} mark
*/
-Changes.addMarks = (change, marks) => {
+Commands.addMarks = (change, marks) => {
marks.forEach(mark => change.addMark(mark))
}
@@ -90,7 +90,7 @@ Changes.addMarks = (change, marks) => {
* @param {Change} change
*/
-Changes.delete = change => {
+Commands.delete = change => {
const { value } = change
const { selection } = value
change.deleteAtRange(selection)
@@ -108,7 +108,7 @@ Changes.delete = change => {
* @param {String|Object|Block} block
*/
-Changes.insertBlock = (change, block) => {
+Commands.insertBlock = (change, block) => {
block = Block.create(block)
const { value } = change
const { selection } = value
@@ -126,7 +126,7 @@ Changes.insertBlock = (change, block) => {
* @param {Document} fragment
*/
-Changes.insertFragment = (change, fragment) => {
+Commands.insertFragment = (change, fragment) => {
if (!fragment.nodes.size) return
let { value } = change
@@ -171,7 +171,7 @@ Changes.insertFragment = (change, fragment) => {
* @param {String|Object|Inline} inline
*/
-Changes.insertInline = (change, inline) => {
+Commands.insertInline = (change, inline) => {
inline = Inline.create(inline)
const { value } = change
const { selection } = value
@@ -190,7 +190,7 @@ Changes.insertInline = (change, inline) => {
* @param {Set} marks (optional)
*/
-Changes.insertText = (change, text, marks) => {
+Commands.insertText = (change, text, marks) => {
const { value } = change
const { document, selection } = value
marks = marks || selection.marks || document.getInsertMarksAtRange(selection)
@@ -210,7 +210,7 @@ Changes.insertText = (change, text, marks) => {
* @param {Mark} mark
*/
-Changes.removeMark = (change, mark) => {
+Commands.removeMark = (change, mark) => {
mark = Mark.create(mark)
const { value } = change
const { document, selection } = value
@@ -236,7 +236,7 @@ Changes.removeMark = (change, mark) => {
* @param {Mark} newMark
*/
-Changes.replaceMark = (change, oldMark, newMark) => {
+Commands.replaceMark = (change, oldMark, newMark) => {
change.removeMark(oldMark)
change.addMark(newMark)
}
@@ -248,7 +248,7 @@ Changes.replaceMark = (change, oldMark, newMark) => {
* @param {Number} depth (optional)
*/
-Changes.splitBlock = (change, depth = 1) => {
+Commands.splitBlock = (change, depth = 1) => {
const { value } = change
const { selection, document } = value
const marks = selection.marks || document.getInsertMarksAtRange(selection)
@@ -267,7 +267,7 @@ Changes.splitBlock = (change, depth = 1) => {
* @param {Mark} mark
*/
-Changes.toggleMark = (change, mark) => {
+Commands.toggleMark = (change, mark) => {
mark = Mark.create(mark)
const { value } = change
const exists = value.activeMarks.has(mark)
@@ -287,7 +287,7 @@ Changes.toggleMark = (change, mark) => {
* @param {String} suffix
*/
-Changes.wrapText = (change, prefix, suffix = prefix) => {
+Commands.wrapText = (change, prefix, suffix = prefix) => {
const { value } = change
const { selection } = value
change.wrapTextAtRange(selection, prefix, suffix)
@@ -314,4 +314,4 @@ Changes.wrapText = (change, prefix, suffix = prefix) => {
* @type {Object}
*/
-export default Changes
+export default Commands
diff --git a/packages/slate/src/changes/at-range.js b/packages/slate/src/commands/at-range.js
similarity index 91%
rename from packages/slate/src/changes/at-range.js
rename to packages/slate/src/commands/at-range.js
index 2535b8ced..fcdcd7326 100644
--- a/packages/slate/src/changes/at-range.js
+++ b/packages/slate/src/commands/at-range.js
@@ -6,12 +6,12 @@ import Node from '../models/node'
import TextUtils from '../utils/text-utils'
/**
- * Changes.
+ * Commands.
*
* @type {Object}
*/
-const Changes = {}
+const Commands = {}
/**
* Add a new `mark` to the characters at `range`.
@@ -21,7 +21,7 @@ const Changes = {}
* @param {Mixed} mark
*/
-Changes.addMarkAtRange = (change, range, mark) => {
+Commands.addMarkAtRange = (change, range, mark) => {
if (range.isCollapsed) return
const { value } = change
@@ -52,7 +52,7 @@ Changes.addMarkAtRange = (change, range, mark) => {
* @param {Array} mark
*/
-Changes.addMarksAtRange = (change, range, marks) => {
+Commands.addMarksAtRange = (change, range, marks) => {
marks.forEach(mark => change.addMarkAtRange(range, mark))
}
@@ -63,22 +63,22 @@ Changes.addMarksAtRange = (change, range, marks) => {
* @param {Range} range
*/
-Changes.deleteAtRange = (change, range) => {
+Commands.deleteAtRange = (change, range) => {
// Snapshot the selection, which creates an extra undo save point, so that
// when you undo a delete, the expanded selection will be retained.
change.snapshotSelection()
- const { value } = change
+ const { editor, value } = change
const { start, end } = range
let startKey = start.key
let startOffset = start.offset
let endKey = end.key
let endOffset = end.offset
- let { document, schema } = value
- let isStartVoid = document.hasVoidParent(startKey, schema)
- let isEndVoid = document.hasVoidParent(endKey, schema)
- let startBlock = document.getClosestBlock(startKey, schema)
- let endBlock = document.getClosestBlock(endKey, schema)
+ let { document } = value
+ let isStartVoid = document.hasVoidParent(startKey, editor)
+ let isEndVoid = document.hasVoidParent(endKey, editor)
+ let startBlock = document.getClosestBlock(startKey)
+ let endBlock = document.getClosestBlock(endKey)
// Check if we have a "hanging" selection case where the even though the
// selection extends into the start of the end node, we actually want to
@@ -95,7 +95,7 @@ Changes.deleteAtRange = (change, range) => {
const prevText = document.getPreviousText(endKey)
endKey = prevText.key
endOffset = prevText.text.length
- isEndVoid = document.hasVoidParent(endKey, schema)
+ isEndVoid = document.hasVoidParent(endKey, editor)
}
change.withoutNormalizing(() => {
@@ -103,7 +103,7 @@ Changes.deleteAtRange = (change, range) => {
// the starting point to be right after it, continuously until the start point
// is not a void, or until the entire range is handled.
while (isStartVoid) {
- const startVoid = document.getClosestVoid(startKey, schema)
+ const startVoid = document.getClosestVoid(startKey, editor)
const nextText = document.getNextText(startKey)
change.removeNodeByKey(startVoid.key)
@@ -117,14 +117,14 @@ Changes.deleteAtRange = (change, range) => {
document = change.value.document
startKey = nextText.key
startOffset = 0
- isStartVoid = document.hasVoidParent(startKey, schema)
+ isStartVoid = document.hasVoidParent(startKey, editor)
}
// If the end node is inside a void node, do the same thing but backwards. But
// we don't need any aborting checks because if we've gotten this far there
// must be a non-void node that will exit the loop.
while (isEndVoid) {
- const endVoid = document.getClosestVoid(endKey, schema)
+ const endVoid = document.getClosestVoid(endKey, editor)
const prevText = document.getPreviousText(endKey)
change.removeNodeByKey(endVoid.key)
@@ -132,7 +132,7 @@ Changes.deleteAtRange = (change, range) => {
document = change.value.document
endKey = prevText.key
endOffset = prevText.text.length
- isEndVoid = document.hasVoidParent(endKey, schema)
+ isEndVoid = document.hasVoidParent(endKey, editor)
}
// If the start and end key are the same, and it was a hanging selection, we
@@ -257,7 +257,7 @@ Changes.deleteAtRange = (change, range) => {
* @param {Range} range
*/
-Changes.deleteCharBackwardAtRange = (change, range) => {
+Commands.deleteCharBackwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -276,7 +276,7 @@ Changes.deleteCharBackwardAtRange = (change, range) => {
* @param {Range} range
*/
-Changes.deleteLineBackwardAtRange = (change, range) => {
+Commands.deleteLineBackwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -293,7 +293,7 @@ Changes.deleteLineBackwardAtRange = (change, range) => {
* @param {Range} range
*/
-Changes.deleteWordBackwardAtRange = (change, range) => {
+Commands.deleteWordBackwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -313,10 +313,10 @@ Changes.deleteWordBackwardAtRange = (change, range) => {
* @param {Number} n (optional)
*/
-Changes.deleteBackwardAtRange = (change, range, n = 1) => {
+Commands.deleteBackwardAtRange = (change, range, n = 1) => {
if (n === 0) return
- const { value } = change
- const { document, schema } = value
+ const { editor, value } = change
+ const { document } = value
const { start, focus } = range
// If the range is expanded, perform a regular delete instead.
@@ -325,7 +325,7 @@ Changes.deleteBackwardAtRange = (change, range, n = 1) => {
return
}
- const voidParent = document.getClosestVoid(start.key, schema)
+ const voidParent = document.getClosestVoid(start.key, editor)
// If there is a void parent, delete it.
if (voidParent) {
@@ -338,7 +338,7 @@ Changes.deleteBackwardAtRange = (change, range, n = 1) => {
// If the closest is not void, but empty, remove it
if (
block &&
- !schema.isVoid(block) &&
+ !change.isVoid(block) &&
block.text === '' &&
document.nodes.size !== 1
) {
@@ -358,7 +358,7 @@ Changes.deleteBackwardAtRange = (change, range, n = 1) => {
if (start.isAtStartOfNode(text)) {
const prev = document.getPreviousText(text.key)
const prevBlock = document.getClosestBlock(prev.key)
- const prevVoid = document.getClosestVoid(prev.key, schema)
+ const prevVoid = document.getClosestVoid(prev.key, editor)
// If the previous text node has a void parent, remove it.
if (prevVoid) {
@@ -411,7 +411,7 @@ Changes.deleteBackwardAtRange = (change, range, n = 1) => {
* @param {Range} range
*/
-Changes.deleteCharForwardAtRange = (change, range) => {
+Commands.deleteCharForwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -430,7 +430,7 @@ Changes.deleteCharForwardAtRange = (change, range) => {
* @param {Range} range
*/
-Changes.deleteLineForwardAtRange = (change, range) => {
+Commands.deleteLineForwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -447,7 +447,7 @@ Changes.deleteLineForwardAtRange = (change, range) => {
* @param {Range} range
*/
-Changes.deleteWordForwardAtRange = (change, range) => {
+Commands.deleteWordForwardAtRange = (change, range) => {
const { value } = change
const { document } = value
const { start } = range
@@ -467,10 +467,10 @@ Changes.deleteWordForwardAtRange = (change, range) => {
* @param {Number} n (optional)
*/
-Changes.deleteForwardAtRange = (change, range, n = 1) => {
+Commands.deleteForwardAtRange = (change, range, n = 1) => {
if (n === 0) return
- const { value } = change
- const { document, schema } = value
+ const { editor, value } = change
+ const { document } = value
const { start, focus } = range
// If the range is expanded, perform a regular delete instead.
@@ -479,7 +479,7 @@ Changes.deleteForwardAtRange = (change, range, n = 1) => {
return
}
- const voidParent = document.getClosestVoid(start.key, schema)
+ const voidParent = document.getClosestVoid(start.key, editor)
// If the node has a void parent, delete it.
if (voidParent) {
@@ -492,7 +492,7 @@ Changes.deleteForwardAtRange = (change, range, n = 1) => {
// If the closest is not void, but empty, remove it
if (
block &&
- !schema.isVoid(block) &&
+ !change.isVoid(block) &&
block.text === '' &&
document.nodes.size !== 1
) {
@@ -518,7 +518,7 @@ Changes.deleteForwardAtRange = (change, range, n = 1) => {
if (start.isAtEndOfNode(text)) {
const next = document.getNextText(text.key)
const nextBlock = document.getClosestBlock(next.key)
- const nextVoid = document.getClosestVoid(next.key, schema)
+ const nextVoid = document.getClosestVoid(next.key, editor)
// If the next text node has a void parent, remove it.
if (nextVoid) {
@@ -573,7 +573,7 @@ Changes.deleteForwardAtRange = (change, range, n = 1) => {
* @param {Block|String|Object} block
*/
-Changes.insertBlockAtRange = (change, range, block) => {
+Commands.insertBlockAtRange = (change, range, block) => {
block = Block.create(block)
if (range.isExpanded) {
@@ -582,7 +582,7 @@ Changes.insertBlockAtRange = (change, range, block) => {
}
const { value } = change
- const { document, schema } = value
+ const { document } = value
const { start } = range
let startKey = start.key
let startOffset = start.offset
@@ -591,7 +591,7 @@ Changes.insertBlockAtRange = (change, range, block) => {
const parent = document.getParent(startBlock.key)
const index = parent.nodes.indexOf(startBlock)
- if (schema.isVoid(startBlock)) {
+ if (change.isVoid(startBlock)) {
const extra = start.isAtEndOfNode(startBlock) ? 1 : 0
change.insertNodeByKey(parent.key, index + extra, block)
} else if (!startInline && startBlock.text === '') {
@@ -601,7 +601,7 @@ Changes.insertBlockAtRange = (change, range, block) => {
} else if (start.isAtEndOfNode(startBlock)) {
change.insertNodeByKey(parent.key, index + 1, block)
} else {
- if (startInline && schema.isVoid(startInline)) {
+ if (startInline && change.isVoid(startInline)) {
const atEnd = start.isAtEndOfNode(startInline)
const siblingText = atEnd
? document.getNextText(startKey)
@@ -630,7 +630,7 @@ Changes.insertBlockAtRange = (change, range, block) => {
* @param {Document} fragment
*/
-Changes.insertFragmentAtRange = (change, range, fragment) => {
+Commands.insertFragmentAtRange = (change, range, fragment) => {
change.withoutNormalizing(() => {
// If the range is expanded, delete it first.
if (range.isExpanded) {
@@ -655,7 +655,6 @@ Changes.insertFragmentAtRange = (change, range, fragment) => {
// Calculate a few things...
const { start } = range
const { value } = change
- const { schema } = value
let { document } = value
let startText = document.getDescendant(start.key)
let startBlock = document.getClosestBlock(startText.key)
@@ -670,7 +669,7 @@ Changes.insertFragmentAtRange = (change, range, fragment) => {
const lastBlock = blocks.last()
// If the fragment only contains a void block, use `insertBlock` instead.
- if (firstBlock === lastBlock && schema.isVoid(firstBlock)) {
+ if (firstBlock === lastBlock && change.isVoid(firstBlock)) {
change.insertBlockAtRange(range, firstBlock)
return
}
@@ -732,7 +731,7 @@ Changes.insertFragmentAtRange = (change, range, fragment) => {
// If the starting block is empty, we replace it entirely with the first block
// of the fragment, since this leads to a more expected behavior for the user.
- if (!schema.isVoid(startBlock) && startBlock.text === '') {
+ if (!change.isVoid(startBlock) && startBlock.text === '') {
change.removeNodeByKey(startBlock.key)
change.insertNodeByKey(parent.key, index, firstBlock)
} else {
@@ -758,7 +757,7 @@ Changes.insertFragmentAtRange = (change, range, fragment) => {
* @param {Inline|String|Object} inline
*/
-Changes.insertInlineAtRange = (change, range, inline) => {
+Commands.insertInlineAtRange = (change, range, inline) => {
inline = Inline.create(inline)
change.withoutNormalizing(() => {
@@ -768,13 +767,13 @@ Changes.insertInlineAtRange = (change, range, inline) => {
}
const { value } = change
- const { document, schema } = value
+ const { document } = value
const { start } = range
const parent = document.getParent(start.key)
const startText = document.assertDescendant(start.key)
const index = parent.nodes.indexOf(startText)
- if (schema.isVoid(parent)) return
+ if (change.isVoid(parent)) return
change.splitNodeByKey(start.key, start.offset)
change.insertNodeByKey(parent.key, index + 1, inline)
@@ -790,15 +789,15 @@ Changes.insertInlineAtRange = (change, range, inline) => {
* @param {Set} marks (optional)
*/
-Changes.insertTextAtRange = (change, range, text, marks) => {
+Commands.insertTextAtRange = (change, range, text, marks) => {
const { value } = change
- const { document, schema } = value
+ const { document } = value
const { start } = range
let key = start.key
let offset = start.offset
const parent = document.getParent(start.key)
- if (schema.isVoid(parent)) {
+ if (change.isVoid(parent)) {
return
}
@@ -825,7 +824,7 @@ Changes.insertTextAtRange = (change, range, text, marks) => {
* @param {Mark|String} mark (optional)
*/
-Changes.removeMarkAtRange = (change, range, mark) => {
+Commands.removeMarkAtRange = (change, range, mark) => {
if (range.isCollapsed) return
const { value } = change
@@ -856,13 +855,13 @@ Changes.removeMarkAtRange = (change, range, mark) => {
* @param {Object|String} properties
*/
-Changes.setBlocksAtRange = (change, range, properties) => {
- const { value } = change
- const { document, schema } = value
+Commands.setBlocksAtRange = (change, range, properties) => {
+ const { editor, value } = change
+ const { document } = value
const blocks = document.getBlocksAtRange(range)
const { start, end, isCollapsed } = range
- const isStartVoid = document.hasVoidParent(start.key, schema)
+ const isStartVoid = document.hasVoidParent(start.key, editor)
const startBlock = document.getClosestBlock(start.key)
const endBlock = document.getClosestBlock(end.key)
@@ -895,7 +894,7 @@ Changes.setBlocksAtRange = (change, range, properties) => {
* @param {Object|String} properties
*/
-Changes.setInlinesAtRange = (change, range, properties) => {
+Commands.setInlinesAtRange = (change, range, properties) => {
const { value } = change
const { document } = value
const inlines = document.getInlinesAtRange(range)
@@ -915,7 +914,7 @@ Changes.setInlinesAtRange = (change, range, properties) => {
* @param {Number} height (optional)
*/
-Changes.splitBlockAtRange = (change, range, height = 1) => {
+Commands.splitBlockAtRange = (change, range, height = 1) => {
const { start, end } = range
let { value } = change
let { document } = value
@@ -959,7 +958,7 @@ Changes.splitBlockAtRange = (change, range, height = 1) => {
* @param {Number} height (optional)
*/
-Changes.splitInlineAtRange = (change, range, height = Infinity) => {
+Commands.splitInlineAtRange = (change, range, height = Infinity) => {
if (range.isExpanded) {
change.deleteAtRange(range)
range = range.moveToStart()
@@ -990,7 +989,7 @@ Changes.splitInlineAtRange = (change, range, height = Infinity) => {
* @param {Mixed} mark
*/
-Changes.toggleMarkAtRange = (change, range, mark) => {
+Commands.toggleMarkAtRange = (change, range, mark) => {
if (range.isCollapsed) return
mark = Mark.create(mark)
@@ -1015,7 +1014,7 @@ Changes.toggleMarkAtRange = (change, range, mark) => {
* @param {String|Object} properties
*/
-Changes.unwrapBlockAtRange = (change, range, properties) => {
+Commands.unwrapBlockAtRange = (change, range, properties) => {
properties = Node.createProperties(properties)
const { value } = change
@@ -1096,7 +1095,7 @@ Changes.unwrapBlockAtRange = (change, range, properties) => {
* @param {String|Object} properties
*/
-Changes.unwrapInlineAtRange = (change, range, properties) => {
+Commands.unwrapInlineAtRange = (change, range, properties) => {
properties = Node.createProperties(properties)
const { value } = change
@@ -1139,7 +1138,7 @@ Changes.unwrapInlineAtRange = (change, range, properties) => {
* @param {Block|Object|String} block
*/
-Changes.wrapBlockAtRange = (change, range, block) => {
+Commands.wrapBlockAtRange = (change, range, block) => {
block = Block.create(block)
block = block.set('nodes', block.nodes.clear())
@@ -1203,16 +1202,16 @@ Changes.wrapBlockAtRange = (change, range, block) => {
* @param {Inline|Object|String} inline
*/
-Changes.wrapInlineAtRange = (change, range, inline) => {
+Commands.wrapInlineAtRange = (change, range, inline) => {
const { value } = change
- let { document, schema } = value
+ let { document } = value
const { start, end } = range
if (range.isCollapsed) {
// Wrapping an inline void
const inlineParent = document.getClosestInline(start.key)
- if (!schema.isVoid(inlineParent)) {
+ if (!change.isVoid(inlineParent)) {
return
}
@@ -1328,7 +1327,7 @@ Changes.wrapInlineAtRange = (change, range, inline) => {
* @param {String} suffix (optional)
*/
-Changes.wrapTextAtRange = (change, range, prefix, suffix = prefix) => {
+Commands.wrapTextAtRange = (change, range, prefix, suffix = prefix) => {
const { start, end } = range
const startRange = range.moveToStart()
let endRange = range.moveToEnd()
@@ -1349,4 +1348,4 @@ Changes.wrapTextAtRange = (change, range, prefix, suffix = prefix) => {
* @type {Object}
*/
-export default Changes
+export default Commands
diff --git a/packages/slate/src/changes/by-path.js b/packages/slate/src/commands/by-path.js
similarity index 83%
rename from packages/slate/src/changes/by-path.js
rename to packages/slate/src/commands/by-path.js
index c875a1369..7e0c039b5 100644
--- a/packages/slate/src/changes/by-path.js
+++ b/packages/slate/src/commands/by-path.js
@@ -5,12 +5,12 @@ import Node from '../models/node'
import PathUtils from '../utils/path-utils'
/**
- * Changes.
+ * Commands.
*
* @type {Object}
*/
-const Changes = {}
+const Commands = {}
/**
* Add mark to text at `offset` and `length` in node by `path`.
@@ -22,7 +22,7 @@ const Changes = {}
* @param {Mixed} mark
*/
-Changes.addMarkByPath = (change, path, offset, length, mark) => {
+Commands.addMarkByPath = (change, path, offset, length, mark) => {
mark = Mark.create(mark)
const { value } = change
const { document } = value
@@ -72,7 +72,7 @@ Changes.addMarkByPath = (change, path, offset, length, mark) => {
* @param {Fragment} fragment
*/
-Changes.insertFragmentByPath = (change, path, index, fragment) => {
+Commands.insertFragmentByPath = (change, path, index, fragment) => {
fragment.nodes.forEach((node, i) => {
change.insertNodeByPath(path, index + i, node)
})
@@ -87,7 +87,7 @@ Changes.insertFragmentByPath = (change, path, index, fragment) => {
* @param {Node} node
*/
-Changes.insertNodeByPath = (change, path, index, node) => {
+Commands.insertNodeByPath = (change, path, index, node) => {
const { value } = change
change.applyOperation({
@@ -108,12 +108,33 @@ Changes.insertNodeByPath = (change, path, index, node) => {
* @param {Set} marks (optional)
*/
-Changes.insertTextByPath = (change, path, offset, text, marks) => {
+Commands.insertTextByPath = (change, path, offset, text, marks) => {
const { value } = change
- const { document } = value
+ const { decorations, document } = value
const node = document.assertNode(path)
marks = marks || node.getMarksAtIndex(offset)
+ let updated = false
+ const { key } = node
+
+ const decs = decorations.filter(dec => {
+ const { start, end, mark } = dec
+ const isAtomic = change.isAtomic(mark)
+ if (!isAtomic) return true
+ if (start.key !== key) return true
+
+ if (start.offset < offset && (end.key !== key || end.offset > offset)) {
+ updated = true
+ return false
+ }
+
+ return true
+ })
+
+ if (updated) {
+ change.setValue({ decorations: decs })
+ }
+
change.applyOperation({
type: 'insert_text',
value,
@@ -131,7 +152,7 @@ Changes.insertTextByPath = (change, path, offset, text, marks) => {
* @param {Array} path
*/
-Changes.mergeNodeByPath = (change, path) => {
+Commands.mergeNodeByPath = (change, path) => {
const { value } = change
const { document } = value
const original = document.getDescendant(path)
@@ -170,7 +191,7 @@ Changes.mergeNodeByPath = (change, path) => {
* @param {Number} index
*/
-Changes.moveNodeByPath = (change, path, newPath, newIndex) => {
+Commands.moveNodeByPath = (change, path, newPath, newIndex) => {
const { value } = change
change.applyOperation({
@@ -191,7 +212,7 @@ Changes.moveNodeByPath = (change, path, newPath, newIndex) => {
* @param {Mark} mark
*/
-Changes.removeMarkByPath = (change, path, offset, length, mark) => {
+Commands.removeMarkByPath = (change, path, offset, length, mark) => {
mark = Mark.create(mark)
const { value } = change
const { document } = value
@@ -239,7 +260,7 @@ Changes.removeMarkByPath = (change, path, offset, length, mark) => {
* @param {Array} path
*/
-Changes.removeAllMarksByPath = (change, path) => {
+Commands.removeAllMarksByPath = (change, path) => {
const { state } = change
const { document } = state
const node = document.assertNode(path)
@@ -259,7 +280,7 @@ Changes.removeAllMarksByPath = (change, path) => {
* @param {Array} path
*/
-Changes.removeNodeByPath = (change, path) => {
+Commands.removeNodeByPath = (change, path) => {
const { value } = change
const { document } = value
const node = document.assertNode(path)
@@ -281,13 +302,41 @@ Changes.removeNodeByPath = (change, path) => {
* @param {Number} length
*/
-Changes.removeTextByPath = (change, path, offset, length) => {
+Commands.removeTextByPath = (change, path, offset, length) => {
const { value } = change
- const { document } = value
+ const { decorations, document } = value
const node = document.assertNode(path)
const leaves = node.getLeaves()
const { text } = node
+ let updated = false
+ const { key } = node
+ const from = offset
+ const to = offset + length
+
+ const decs = decorations.filter(dec => {
+ const { start, end, mark } = dec
+ const isAtomic = change.isAtomic(mark)
+ if (!isAtomic) return true
+ if (start.key !== key) return true
+
+ if (start.offset < from && (end.key !== key || end.offset > from)) {
+ updated = true
+ return false
+ }
+
+ if (start.offset < to && (end.key !== key || end.offset > to)) {
+ updated = true
+ return null
+ }
+
+ return true
+ })
+
+ if (updated) {
+ change.setValue({ decorations: decs })
+ }
+
const removals = []
const bx = offset
const by = offset + length
@@ -329,7 +378,7 @@ Changes.removeTextByPath = (change, path, offset, length) => {
* @param {Object|Node} node
*/
-Changes.replaceNodeByPath = (change, path, newNode) => {
+Commands.replaceNodeByPath = (change, path, newNode) => {
newNode = Node.create(newNode)
const index = path.last()
const parentPath = PathUtils.lift(path)
@@ -350,7 +399,7 @@ Changes.replaceNodeByPath = (change, path, newNode) => {
* @param {Set} marks (optional)
*/
-Changes.replaceTextByPath = (change, path, offset, length, text, marks) => {
+Commands.replaceTextByPath = (change, path, offset, length, text, marks) => {
const { document } = change.value
const node = document.assertNode(path)
@@ -395,7 +444,7 @@ Changes.replaceTextByPath = (change, path, offset, length, text, marks) => {
* @param {Mark} mark
*/
-Changes.setMarkByPath = (change, path, offset, length, mark, properties) => {
+Commands.setMarkByPath = (change, path, offset, length, mark, properties) => {
mark = Mark.create(mark)
properties = Mark.createProperties(properties)
const { value } = change
@@ -419,7 +468,7 @@ Changes.setMarkByPath = (change, path, offset, length, mark, properties) => {
* @param {Object|String} properties
*/
-Changes.setNodeByPath = (change, path, properties) => {
+Commands.setNodeByPath = (change, path, properties) => {
properties = Node.createProperties(properties)
const { value } = change
const { document } = value
@@ -443,7 +492,7 @@ Changes.setNodeByPath = (change, path, properties) => {
* @param {Set} marks (optional)
*/
-Changes.setTextByPath = (change, path, text, marks) => {
+Commands.setTextByPath = (change, path, text, marks) => {
const { value } = change
const { document } = value
const node = document.assertNode(path)
@@ -460,7 +509,7 @@ Changes.setTextByPath = (change, path, text, marks) => {
* @param {Object} options
*/
-Changes.splitNodeByPath = (change, path, position, options = {}) => {
+Commands.splitNodeByPath = (change, path, position, options = {}) => {
const { target = null } = options
const { value } = change
const { document } = value
@@ -488,7 +537,7 @@ Changes.splitNodeByPath = (change, path, position, options = {}) => {
* @param {Number} textOffset
*/
-Changes.splitDescendantsByPath = (change, path, textPath, textOffset) => {
+Commands.splitDescendantsByPath = (change, path, textPath, textOffset) => {
if (path.equals(textPath)) {
change.splitNodeByPath(textPath, textOffset)
return
@@ -525,7 +574,7 @@ Changes.splitDescendantsByPath = (change, path, textPath, textOffset) => {
* @param {Object|String} properties
*/
-Changes.unwrapInlineByPath = (change, path, properties) => {
+Commands.unwrapInlineByPath = (change, path, properties) => {
const { value } = change
const { document, selection } = value
const node = document.assertNode(path)
@@ -543,7 +592,7 @@ Changes.unwrapInlineByPath = (change, path, properties) => {
* @param {Object|String} properties
*/
-Changes.unwrapBlockByPath = (change, path, properties) => {
+Commands.unwrapBlockByPath = (change, path, properties) => {
const { value } = change
const { document, selection } = value
const node = document.assertNode(path)
@@ -564,7 +613,7 @@ Changes.unwrapBlockByPath = (change, path, properties) => {
* @param {Array} path
*/
-Changes.unwrapNodeByPath = (change, path) => {
+Commands.unwrapNodeByPath = (change, path) => {
const { value } = change
const { document } = value
document.assertNode(path)
@@ -602,7 +651,7 @@ Changes.unwrapNodeByPath = (change, path) => {
* @param {Block|Object|String} block
*/
-Changes.wrapBlockByPath = (change, path, block) => {
+Commands.wrapBlockByPath = (change, path, block) => {
block = Block.create(block)
block = block.set('nodes', block.nodes.clear())
const parentPath = PathUtils.lift(path)
@@ -623,7 +672,7 @@ Changes.wrapBlockByPath = (change, path, block) => {
* @param {Block|Object|String} inline
*/
-Changes.wrapInlineByPath = (change, path, inline) => {
+Commands.wrapInlineByPath = (change, path, inline) => {
inline = Inline.create(inline)
inline = inline.set('nodes', inline.nodes.clear())
const parentPath = PathUtils.lift(path)
@@ -644,7 +693,7 @@ Changes.wrapInlineByPath = (change, path, inline) => {
* @param {Node|Object} node
*/
-Changes.wrapNodeByPath = (change, path, node) => {
+Commands.wrapNodeByPath = (change, path, node) => {
node = Node.create(node)
if (node.object === 'block') {
@@ -658,7 +707,7 @@ Changes.wrapNodeByPath = (change, path, node) => {
* Mix in `*ByKey` variants.
*/
-const CHANGES = [
+const COMMANDS = [
'addMark',
'insertFragment',
'insertNode',
@@ -682,8 +731,8 @@ const CHANGES = [
'wrapNode',
]
-for (const method of CHANGES) {
- Changes[`${method}ByKey`] = (change, key, ...args) => {
+for (const method of COMMANDS) {
+ Commands[`${method}ByKey`] = (change, key, ...args) => {
const { value } = change
const { document } = value
const path = document.assertPath(key)
@@ -692,7 +741,7 @@ for (const method of CHANGES) {
}
// Moving nodes takes two keys, so it's slightly different.
-Changes.moveNodeByKey = (change, key, newKey, ...args) => {
+Commands.moveNodeByKey = (change, key, newKey, ...args) => {
const { value } = change
const { document } = value
const path = document.assertPath(key)
@@ -701,7 +750,7 @@ Changes.moveNodeByKey = (change, key, newKey, ...args) => {
}
// Splitting descendants takes two keys, so it's slightly different.
-Changes.splitDescendantsByKey = (change, key, textKey, ...args) => {
+Commands.splitDescendantsByKey = (change, key, textKey, ...args) => {
const { value } = change
const { document } = value
const path = document.assertPath(key)
@@ -715,4 +764,4 @@ Changes.splitDescendantsByKey = (change, key, textKey, ...args) => {
* @type {Object}
*/
-export default Changes
+export default Commands
diff --git a/packages/slate/src/commands/on-history.js b/packages/slate/src/commands/on-history.js
new file mode 100644
index 000000000..c9f6c1a32
--- /dev/null
+++ b/packages/slate/src/commands/on-history.js
@@ -0,0 +1,200 @@
+import omit from 'lodash/omit'
+import { List } from 'immutable'
+
+/**
+ * Commands.
+ *
+ * @type {Object}
+ */
+
+const Commands = {}
+
+/**
+ * Save an `operation` into the history.
+ *
+ * @param {Change} change
+ * @param {Object} operation
+ */
+
+Commands.save = (change, operation) => {
+ const { operations, value } = change
+ const { data } = value
+ let { save, merge } = change.tmp
+ if (save === false) return
+
+ let undos = data.get('undos') || List()
+ const lastBatch = undos.last()
+ const lastOperation = lastBatch && lastBatch.last()
+
+ // If `merge` is non-commital, and this is not the first operation in a new
+ // change, then merge, otherwise merge based on the last operation.
+ if (merge == null) {
+ if (operations.size !== 0) {
+ merge = true
+ } else {
+ merge = shouldMerge(operation, lastOperation)
+ }
+ }
+
+ // If the `merge` flag is true, add the operation to the last batch.
+ if (merge && lastBatch) {
+ const batch = lastBatch.push(operation)
+ undos = undos.pop()
+ undos = undos.push(batch)
+ } else {
+ // Otherwise, create a new batch with the operation.
+ const batch = List([operation])
+ undos = undos.push(batch)
+ }
+
+ // Constrain the history to 100 entries for memory's sake.
+ if (undos.size > 100) {
+ undos = undos.takeLast(100)
+ }
+
+ // Clear the redos and update the history.
+ change.withoutSaving(() => {
+ const redos = List()
+ const newData = data.set('undos', undos).set('redos', redos)
+ change.setValue({ data: newData })
+ })
+}
+
+/**
+ * Redo to the next value in the history.
+ *
+ * @param {Change} change
+ */
+
+Commands.redo = change => {
+ const { value } = change
+ const { data } = value
+ let redos = data.get('redos') || List()
+ let undos = data.get('undos') || List()
+ const batch = redos.last()
+ if (!batch) return
+
+ change.withoutSaving(() => {
+ // Replay the batch of operations.
+ batch.forEach(op => {
+ const { type, properties } = op
+
+ // When the operation mutates the selection, omit its `isFocused` value to
+ // prevent the editor focus from changing during redoing.
+ if (type === 'set_selection') {
+ op = op.set('properties', omit(properties, 'isFocused'))
+ }
+
+ change.applyOperation(op)
+ })
+
+ // Shift the next value into the undo stack.
+ redos = redos.pop()
+ undos = undos.push(batch)
+ const newData = data.set('undos', undos).set('redos', redos)
+ change.setValue({ data: newData })
+ })
+}
+
+/**
+ * Undo the previous operations in the history.
+ *
+ * @param {Change} change
+ */
+
+Commands.undo = change => {
+ const { value } = change
+ const { data } = value
+ let redos = data.get('redos') || List()
+ let undos = data.get('undos') || List()
+ const batch = undos.last()
+ if (!batch) return
+
+ change.withoutSaving(() => {
+ // Replay the inverse of the previous operations.
+ batch
+ .slice()
+ .reverse()
+ .map(op => op.invert())
+ .forEach(inverse => {
+ const { type, properties } = inverse
+
+ // When the operation mutates the selection, omit its `isFocused` value to
+ // prevent the editor focus from changing during undoing.
+ if (type === 'set_selection') {
+ inverse = inverse.set('properties', omit(properties, 'isFocused'))
+ }
+
+ change.applyOperation(inverse)
+ })
+
+ // Shift the previous operations into the redo stack.
+ redos = redos.push(batch)
+ undos = undos.pop()
+ const newData = data.set('undos', undos).set('redos', redos)
+ change.setValue({ data: newData })
+ })
+}
+
+/**
+ * Apply a series of changes inside a synchronous `fn`, without merging any of
+ * the new operations into previous save point in the history.
+ *
+ * @param {Change} change
+ * @param {Function} fn
+ */
+
+Commands.withoutMerging = (change, fn) => {
+ const value = change.tmp.merge
+ change.tmp.merge = false
+ fn(change)
+ change.tmp.merge = value
+}
+
+/**
+ * Apply a series of changes inside a synchronous `fn`, without saving any of
+ * their operations into the history.
+ *
+ * @param {Change}
+ * @param {Function} fn
+ */
+
+Commands.withoutSaving = (change, fn) => {
+ const value = change.tmp.save
+ change.tmp.save = false
+ fn(change)
+ change.tmp.save = value
+}
+
+/**
+ * Check whether to merge a new operation `o` into the previous operation `p`.
+ *
+ * @param {Object} o
+ * @param {Object} p
+ * @return {Boolean}
+ */
+
+function shouldMerge(o, p) {
+ if (!p) return false
+
+ const merge =
+ (o.type === 'set_selection' && p.type === 'set_selection') ||
+ (o.type === 'insert_text' &&
+ p.type === 'insert_text' &&
+ o.offset === p.offset + p.text.length &&
+ o.path.equals(p.path)) ||
+ (o.type === 'remove_text' &&
+ p.type === 'remove_text' &&
+ o.offset + o.text.length === p.offset &&
+ o.path.equals(p.path))
+
+ return merge
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default Commands
diff --git a/packages/slate/src/changes/on-selection.js b/packages/slate/src/commands/on-selection.js
similarity index 64%
rename from packages/slate/src/changes/on-selection.js
rename to packages/slate/src/commands/on-selection.js
index 13fbf9635..c92e586d6 100644
--- a/packages/slate/src/changes/on-selection.js
+++ b/packages/slate/src/commands/on-selection.js
@@ -3,550 +3,550 @@ import pick from 'lodash/pick'
import Selection from '../models/selection'
-const Changes = {}
+const Commands = {}
-Changes.blur = change => {
+Commands.blur = change => {
change.select({ isFocused: false })
}
-Changes.deselect = change => {
+Commands.deselect = change => {
const range = Selection.create()
change.select(range)
}
-Changes.focus = change => {
+Commands.focus = change => {
change.select({ isFocused: true })
}
-Changes.flip = change => {
+Commands.flip = change => {
change.call(proxy, 'flip')
}
-Changes.moveAnchorBackward = (change, ...args) => {
+Commands.moveAnchorBackward = (change, ...args) => {
change.call(pointBackward, 'anchor', ...args)
}
-Changes.moveAnchorForward = (change, ...args) => {
+Commands.moveAnchorForward = (change, ...args) => {
change.call(pointForward, 'anchor', ...args)
}
-Changes.moveAnchorTo = (change, ...args) => {
+Commands.moveAnchorTo = (change, ...args) => {
change.call(proxy, 'moveAnchorTo', ...args)
}
-Changes.moveAnchorToEndOfBlock = change => {
+Commands.moveAnchorToEndOfBlock = change => {
change.call(pointEdgeObject, 'anchor', 'end', 'block')
}
-Changes.moveAnchorToEndOfInline = change => {
+Commands.moveAnchorToEndOfInline = change => {
change.call(pointEdgeObject, 'anchor', 'end', 'inline')
}
-Changes.moveAnchorToEndOfDocument = change => {
+Commands.moveAnchorToEndOfDocument = change => {
change.moveAnchorToEndOfNode(change.value.document).moveToAnchor()
}
-Changes.moveAnchorToEndOfNextBlock = change => {
+Commands.moveAnchorToEndOfNextBlock = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'next', 'block')
}
-Changes.moveAnchorToEndOfNextInline = change => {
+Commands.moveAnchorToEndOfNextInline = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'next', 'inline')
}
-Changes.moveAnchorToEndOfNextText = change => {
+Commands.moveAnchorToEndOfNextText = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'next', 'text')
}
-Changes.moveAnchorToEndOfNode = (change, ...args) => {
+Commands.moveAnchorToEndOfNode = (change, ...args) => {
change.call(proxy, 'moveAnchorToEndOfNode', ...args)
}
-Changes.moveAnchorToEndOfPreviousBlock = change => {
+Commands.moveAnchorToEndOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'previous', 'block')
}
-Changes.moveAnchorToEndOfPreviousInline = change => {
+Commands.moveAnchorToEndOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'previous', 'inline')
}
-Changes.moveAnchorToEndOfPreviousText = change => {
+Commands.moveAnchorToEndOfPreviousText = change => {
change.call(pointEdgeSideObject, 'anchor', 'end', 'previous', 'text')
}
-Changes.moveAnchorToEndOfText = change => {
+Commands.moveAnchorToEndOfText = change => {
change.call(pointEdgeObject, 'anchor', 'end', 'text')
}
-Changes.moveAnchorToStartOfBlock = change => {
+Commands.moveAnchorToStartOfBlock = change => {
change.call(pointEdgeObject, 'anchor', 'start', 'block')
}
-Changes.moveAnchorToStartOfDocument = change => {
+Commands.moveAnchorToStartOfDocument = change => {
change.moveAnchorToStartOfNode(change.value.document).moveToAnchor()
}
-Changes.moveAnchorToStartOfInline = change => {
+Commands.moveAnchorToStartOfInline = change => {
change.call(pointEdgeObject, 'anchor', 'start', 'inline')
}
-Changes.moveAnchorToStartOfNextBlock = change => {
+Commands.moveAnchorToStartOfNextBlock = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'next', 'block')
}
-Changes.moveAnchorToStartOfNextInline = change => {
+Commands.moveAnchorToStartOfNextInline = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'next', 'inline')
}
-Changes.moveAnchorToStartOfNextText = change => {
+Commands.moveAnchorToStartOfNextText = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'next', 'text')
}
-Changes.moveAnchorToStartOfNode = (change, ...args) => {
+Commands.moveAnchorToStartOfNode = (change, ...args) => {
change.call(proxy, 'moveAnchorToStartOfNode', ...args)
}
-Changes.moveAnchorToStartOfPreviousBlock = change => {
+Commands.moveAnchorToStartOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'previous', 'block')
}
-Changes.moveAnchorToStartOfPreviousInline = change => {
+Commands.moveAnchorToStartOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'previous', 'inline')
}
-Changes.moveAnchorToStartOfPreviousText = change => {
+Commands.moveAnchorToStartOfPreviousText = change => {
change.call(pointEdgeSideObject, 'anchor', 'start', 'previous', 'text')
}
-Changes.moveAnchorToStartOfText = change => {
+Commands.moveAnchorToStartOfText = change => {
change.call(pointEdgeObject, 'anchor', 'start', 'text')
}
-Changes.moveBackward = (change, ...args) => {
+Commands.moveBackward = (change, ...args) => {
change.moveAnchorBackward(...args).moveFocusBackward(...args)
}
-Changes.moveEndBackward = (change, ...args) => {
+Commands.moveEndBackward = (change, ...args) => {
change.call(pointBackward, 'end', ...args)
}
-Changes.moveEndForward = (change, ...args) => {
+Commands.moveEndForward = (change, ...args) => {
change.call(pointForward, 'end', ...args)
}
-Changes.moveEndTo = (change, ...args) => {
+Commands.moveEndTo = (change, ...args) => {
change.call(proxy, 'moveEndTo', ...args)
}
-Changes.moveEndToEndOfBlock = change => {
+Commands.moveEndToEndOfBlock = change => {
change.call(pointEdgeObject, 'end', 'end', 'block')
}
-Changes.moveEndToEndOfDocument = change => {
+Commands.moveEndToEndOfDocument = change => {
change.moveEndToEndOfNode(change.value.document).moveToEnd()
}
-Changes.moveEndToEndOfInline = change => {
+Commands.moveEndToEndOfInline = change => {
change.call(pointEdgeObject, 'end', 'end', 'inline')
}
-Changes.moveEndToEndOfNextBlock = change => {
+Commands.moveEndToEndOfNextBlock = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'next', 'block')
}
-Changes.moveEndToEndOfNextInline = change => {
+Commands.moveEndToEndOfNextInline = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'next', 'inline')
}
-Changes.moveEndToEndOfNextText = change => {
+Commands.moveEndToEndOfNextText = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'next', 'text')
}
-Changes.moveEndToEndOfNode = (change, ...args) => {
+Commands.moveEndToEndOfNode = (change, ...args) => {
change.call(proxy, 'moveEndToEndOfNode', ...args)
}
-Changes.moveEndToEndOfPreviousBlock = change => {
+Commands.moveEndToEndOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'previous', 'block')
}
-Changes.moveEndToEndOfPreviousInline = change => {
+Commands.moveEndToEndOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'previous', 'inline')
}
-Changes.moveEndToEndOfPreviousText = change => {
+Commands.moveEndToEndOfPreviousText = change => {
change.call(pointEdgeSideObject, 'end', 'end', 'previous', 'text')
}
-Changes.moveEndToEndOfText = change => {
+Commands.moveEndToEndOfText = change => {
change.call(pointEdgeObject, 'end', 'end', 'text')
}
-Changes.moveEndToStartOfBlock = change => {
+Commands.moveEndToStartOfBlock = change => {
change.call(pointEdgeObject, 'end', 'start', 'block')
}
-Changes.moveEndToStartOfDocument = change => {
+Commands.moveEndToStartOfDocument = change => {
change.moveEndToStartOfNode(change.value.document).moveToEnd()
}
-Changes.moveEndToStartOfInline = change => {
+Commands.moveEndToStartOfInline = change => {
change.call(pointEdgeObject, 'end', 'start', 'inline')
}
-Changes.moveEndToStartOfNextBlock = change => {
+Commands.moveEndToStartOfNextBlock = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'next', 'block')
}
-Changes.moveEndToStartOfNextInline = change => {
+Commands.moveEndToStartOfNextInline = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'next', 'inline')
}
-Changes.moveEndToStartOfNextText = change => {
+Commands.moveEndToStartOfNextText = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'next', 'text')
}
-Changes.moveEndToStartOfNode = (change, ...args) => {
+Commands.moveEndToStartOfNode = (change, ...args) => {
change.call(proxy, 'moveEndToStartOfNode', ...args)
}
-Changes.moveEndToStartOfPreviousBlock = change => {
+Commands.moveEndToStartOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'previous', 'block')
}
-Changes.moveEndToStartOfPreviousInline = change => {
+Commands.moveEndToStartOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'previous', 'inline')
}
-Changes.moveEndToStartOfPreviousText = change => {
+Commands.moveEndToStartOfPreviousText = change => {
change.call(pointEdgeSideObject, 'end', 'start', 'previous', 'text')
}
-Changes.moveEndToStartOfText = change => {
+Commands.moveEndToStartOfText = change => {
change.call(pointEdgeObject, 'end', 'start', 'text')
}
-Changes.moveFocusBackward = (change, ...args) => {
+Commands.moveFocusBackward = (change, ...args) => {
change.call(pointBackward, 'focus', ...args)
}
-Changes.moveFocusForward = (change, ...args) => {
+Commands.moveFocusForward = (change, ...args) => {
change.call(pointForward, 'focus', ...args)
}
-Changes.moveFocusTo = (change, ...args) => {
+Commands.moveFocusTo = (change, ...args) => {
change.call(proxy, 'moveFocusTo', ...args)
}
-Changes.moveFocusToEndOfBlock = change => {
+Commands.moveFocusToEndOfBlock = change => {
change.call(pointEdgeObject, 'focus', 'end', 'block')
}
-Changes.moveFocusToEndOfDocument = change => {
+Commands.moveFocusToEndOfDocument = change => {
change.moveFocusToEndOfNode(change.value.document).moveToFocus()
}
-Changes.moveFocusToEndOfInline = change => {
+Commands.moveFocusToEndOfInline = change => {
change.call(pointEdgeObject, 'focus', 'end', 'inline')
}
-Changes.moveFocusToEndOfNextBlock = change => {
+Commands.moveFocusToEndOfNextBlock = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'next', 'block')
}
-Changes.moveFocusToEndOfNextInline = change => {
+Commands.moveFocusToEndOfNextInline = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'next', 'inline')
}
-Changes.moveFocusToEndOfNextText = change => {
+Commands.moveFocusToEndOfNextText = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'next', 'text')
}
-Changes.moveFocusToEndOfNode = (change, ...args) => {
+Commands.moveFocusToEndOfNode = (change, ...args) => {
change.call(proxy, 'moveFocusToEndOfNode', ...args)
}
-Changes.moveFocusToEndOfPreviousBlock = change => {
+Commands.moveFocusToEndOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'previous', 'block')
}
-Changes.moveFocusToEndOfPreviousInline = change => {
+Commands.moveFocusToEndOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'previous', 'inline')
}
-Changes.moveFocusToEndOfPreviousText = change => {
+Commands.moveFocusToEndOfPreviousText = change => {
change.call(pointEdgeSideObject, 'focus', 'end', 'previous', 'text')
}
-Changes.moveFocusToEndOfText = change => {
+Commands.moveFocusToEndOfText = change => {
change.call(pointEdgeObject, 'focus', 'end', 'text')
}
-Changes.moveFocusToStartOfBlock = change => {
+Commands.moveFocusToStartOfBlock = change => {
change.call(pointEdgeObject, 'focus', 'start', 'block')
}
-Changes.moveFocusToStartOfDocument = change => {
+Commands.moveFocusToStartOfDocument = change => {
change.moveFocusToStartOfNode(change.value.document).moveToFocus()
}
-Changes.moveFocusToStartOfInline = change => {
+Commands.moveFocusToStartOfInline = change => {
change.call(pointEdgeObject, 'focus', 'start', 'inline')
}
-Changes.moveFocusToStartOfNextBlock = change => {
+Commands.moveFocusToStartOfNextBlock = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'next', 'block')
}
-Changes.moveFocusToStartOfNextInline = change => {
+Commands.moveFocusToStartOfNextInline = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'next', 'inline')
}
-Changes.moveFocusToStartOfNextText = change => {
+Commands.moveFocusToStartOfNextText = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'next', 'text')
}
-Changes.moveFocusToStartOfNode = (change, ...args) => {
+Commands.moveFocusToStartOfNode = (change, ...args) => {
change.call(proxy, 'moveFocusToStartOfNode', ...args)
}
-Changes.moveFocusToStartOfPreviousBlock = change => {
+Commands.moveFocusToStartOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'previous', 'block')
}
-Changes.moveFocusToStartOfPreviousInline = change => {
+Commands.moveFocusToStartOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'previous', 'inline')
}
-Changes.moveFocusToStartOfPreviousText = change => {
+Commands.moveFocusToStartOfPreviousText = change => {
change.call(pointEdgeSideObject, 'focus', 'start', 'previous', 'text')
}
-Changes.moveFocusToStartOfText = change => {
+Commands.moveFocusToStartOfText = change => {
change.call(pointEdgeObject, 'focus', 'start', 'text')
}
-Changes.moveForward = (change, ...args) => {
+Commands.moveForward = (change, ...args) => {
change.moveAnchorForward(...args).moveFocusForward(...args)
}
-Changes.moveStartBackward = (change, ...args) => {
+Commands.moveStartBackward = (change, ...args) => {
change.call(pointBackward, 'start', ...args)
}
-Changes.moveStartForward = (change, ...args) => {
+Commands.moveStartForward = (change, ...args) => {
change.call(pointForward, 'start', ...args)
}
-Changes.moveStartTo = (change, ...args) => {
+Commands.moveStartTo = (change, ...args) => {
change.call(proxy, 'moveStartTo', ...args)
}
-Changes.moveStartToEndOfBlock = change => {
+Commands.moveStartToEndOfBlock = change => {
change.call(pointEdgeObject, 'start', 'end', 'block')
}
-Changes.moveStartToEndOfDocument = change => {
+Commands.moveStartToEndOfDocument = change => {
change.moveStartToEndOfNode(change.value.document).moveToStart()
}
-Changes.moveStartToEndOfInline = change => {
+Commands.moveStartToEndOfInline = change => {
change.call(pointEdgeObject, 'start', 'end', 'inline')
}
-Changes.moveStartToEndOfNextBlock = change => {
+Commands.moveStartToEndOfNextBlock = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'next', 'block')
}
-Changes.moveStartToEndOfNextInline = change => {
+Commands.moveStartToEndOfNextInline = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'next', 'inline')
}
-Changes.moveStartToEndOfNextText = change => {
+Commands.moveStartToEndOfNextText = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'next', 'text')
}
-Changes.moveStartToEndOfNode = (change, ...args) => {
+Commands.moveStartToEndOfNode = (change, ...args) => {
change.call(proxy, 'moveStartToEndOfNode', ...args)
}
-Changes.moveStartToEndOfPreviousBlock = change => {
+Commands.moveStartToEndOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'previous', 'block')
}
-Changes.moveStartToEndOfPreviousInline = change => {
+Commands.moveStartToEndOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'previous', 'inline')
}
-Changes.moveStartToEndOfPreviousText = change => {
+Commands.moveStartToEndOfPreviousText = change => {
change.call(pointEdgeSideObject, 'start', 'end', 'previous', 'text')
}
-Changes.moveStartToEndOfText = change => {
+Commands.moveStartToEndOfText = change => {
change.call(pointEdgeObject, 'start', 'end', 'text')
}
-Changes.moveStartToStartOfBlock = change => {
+Commands.moveStartToStartOfBlock = change => {
change.call(pointEdgeObject, 'start', 'start', 'block')
}
-Changes.moveStartToStartOfDocument = change => {
+Commands.moveStartToStartOfDocument = change => {
change.moveStartToStartOfNode(change.value.document).moveToStart()
}
-Changes.moveStartToStartOfInline = change => {
+Commands.moveStartToStartOfInline = change => {
change.call(pointEdgeObject, 'start', 'start', 'inline')
}
-Changes.moveStartToStartOfNextBlock = change => {
+Commands.moveStartToStartOfNextBlock = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'next', 'block')
}
-Changes.moveStartToStartOfNextInline = change => {
+Commands.moveStartToStartOfNextInline = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'next', 'inline')
}
-Changes.moveStartToStartOfNextText = change => {
+Commands.moveStartToStartOfNextText = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'next', 'text')
}
-Changes.moveStartToStartOfNode = (change, ...args) => {
+Commands.moveStartToStartOfNode = (change, ...args) => {
change.call(proxy, 'moveStartToStartOfNode', ...args)
}
-Changes.moveStartToStartOfPreviousBlock = change => {
+Commands.moveStartToStartOfPreviousBlock = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'previous', 'block')
}
-Changes.moveStartToStartOfPreviousInline = change => {
+Commands.moveStartToStartOfPreviousInline = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'previous', 'inline')
}
-Changes.moveStartToStartOfPreviousText = change => {
+Commands.moveStartToStartOfPreviousText = change => {
change.call(pointEdgeSideObject, 'start', 'start', 'previous', 'text')
}
-Changes.moveStartToStartOfText = change => {
+Commands.moveStartToStartOfText = change => {
change.call(pointEdgeObject, 'start', 'start', 'text')
}
-Changes.moveTo = (change, ...args) => {
+Commands.moveTo = (change, ...args) => {
change.call(proxy, 'moveTo', ...args)
}
-Changes.moveToAnchor = change => {
+Commands.moveToAnchor = change => {
change.call(proxy, 'moveToAnchor')
}
-Changes.moveToEnd = change => {
+Commands.moveToEnd = change => {
change.call(proxy, 'moveToEnd')
}
-Changes.moveToEndOfBlock = change => {
+Commands.moveToEndOfBlock = change => {
change.moveEndToEndOfBlock().moveToEnd()
}
-Changes.moveToEndOfDocument = change => {
+Commands.moveToEndOfDocument = change => {
change.moveEndToEndOfNode(change.value.document).moveToEnd()
}
-Changes.moveToEndOfInline = change => {
+Commands.moveToEndOfInline = change => {
change.moveEndToEndOfInline().moveToEnd()
}
-Changes.moveToEndOfNextBlock = change => {
+Commands.moveToEndOfNextBlock = change => {
change.moveEndToEndOfNextBlock().moveToEnd()
}
-Changes.moveToEndOfNextInline = change => {
+Commands.moveToEndOfNextInline = change => {
change.moveEndToEndOfNextInline().moveToEnd()
}
-Changes.moveToEndOfNextText = change => {
+Commands.moveToEndOfNextText = change => {
change.moveEndToEndOfNextText().moveToEnd()
}
-Changes.moveToEndOfNode = (change, ...args) => {
+Commands.moveToEndOfNode = (change, ...args) => {
change.call(proxy, 'moveToEndOfNode', ...args)
}
-Changes.moveToEndOfPreviousBlock = change => {
+Commands.moveToEndOfPreviousBlock = change => {
change.moveStartToEndOfPreviousBlock().moveToStart()
}
-Changes.moveToEndOfPreviousInline = change => {
+Commands.moveToEndOfPreviousInline = change => {
change.moveStartToEndOfPreviousInline().moveToStart()
}
-Changes.moveToEndOfPreviousText = change => {
+Commands.moveToEndOfPreviousText = change => {
change.moveStartToEndOfPreviousText().moveToStart()
}
-Changes.moveToEndOfText = change => {
+Commands.moveToEndOfText = change => {
change.moveEndToEndOfText().moveToEnd()
}
-Changes.moveToFocus = change => {
+Commands.moveToFocus = change => {
change.call(proxy, 'moveToFocus')
}
-Changes.moveToRangeOfDocument = change => {
+Commands.moveToRangeOfDocument = change => {
change.moveToRangeOfNode(change.value.document)
}
-Changes.moveToRangeOfNode = (change, ...args) => {
+Commands.moveToRangeOfNode = (change, ...args) => {
change.call(proxy, 'moveToRangeOfNode', ...args)
}
-Changes.moveToStart = change => {
+Commands.moveToStart = change => {
change.call(proxy, 'moveToStart')
}
-Changes.moveToStartOfBlock = change => {
+Commands.moveToStartOfBlock = change => {
change.moveStartToStartOfBlock().moveToStart()
}
-Changes.moveToStartOfDocument = change => {
+Commands.moveToStartOfDocument = change => {
change.moveStartToStartOfNode(change.value.document).moveToStart()
}
-Changes.moveToStartOfInline = change => {
+Commands.moveToStartOfInline = change => {
change.moveStartToStartOfInline().moveToStart()
}
-Changes.moveToStartOfNextBlock = change => {
+Commands.moveToStartOfNextBlock = change => {
change.moveEndToStartOfNextBlock().moveToEnd()
}
-Changes.moveToStartOfNextInline = change => {
+Commands.moveToStartOfNextInline = change => {
change.moveEndToStartOfNextInline().moveToEnd()
}
-Changes.moveToStartOfNextText = change => {
+Commands.moveToStartOfNextText = change => {
change.moveEndToStartOfNextText().moveToEnd()
}
-Changes.moveToStartOfNode = (change, ...args) => {
+Commands.moveToStartOfNode = (change, ...args) => {
change.call(proxy, 'moveToStartOfNode', ...args)
}
-Changes.moveToStartOfPreviousBlock = change => {
+Commands.moveToStartOfPreviousBlock = change => {
change.moveStartToStartOfPreviousBlock().moveToStart()
}
-Changes.moveToStartOfPreviousInline = change => {
+Commands.moveToStartOfPreviousInline = change => {
change.moveStartToStartOfPreviousInline().moveToStart()
}
-Changes.moveToStartOfPreviousText = change => {
+Commands.moveToStartOfPreviousText = change => {
change.moveStartToStartOfPreviousText().moveToStart()
}
-Changes.moveToStartOfText = change => {
+Commands.moveToStartOfText = change => {
change.moveStartToStartOfText().moveToStart()
}
-Changes.select = (change, properties, options = {}) => {
+Commands.select = (change, properties, options = {}) => {
properties = Selection.createProperties(properties)
const { snapshot = false } = options
const { value } = change
@@ -589,26 +589,26 @@ Changes.select = (change, properties, options = {}) => {
)
}
-Changes.setAnchor = (change, ...args) => {
+Commands.setAnchor = (change, ...args) => {
change.call(proxy, 'setAnchor', ...args)
}
-Changes.setEnd = (change, ...args) => {
+Commands.setEnd = (change, ...args) => {
change.call(proxy, 'setEnd', ...args)
}
-Changes.setFocus = (change, ...args) => {
+Commands.setFocus = (change, ...args) => {
change.call(proxy, 'setFocus', ...args)
}
-Changes.setStart = (change, ...args) => {
+Commands.setStart = (change, ...args) => {
change.call(proxy, 'setStart', ...args)
}
-Changes.snapshotSelection = change => {
- change.withoutMerging(c =>
- c.select(change.value.selection, { snapshot: true })
- )
+Commands.snapshotSelection = change => {
+ change.withoutMerging(() => {
+ change.select(change.value.selection, { snapshot: true })
+ })
}
/**
@@ -657,10 +657,10 @@ function pointBackward(change, point, n = 1) {
if (n < 0) return pointForward(change, point, -n)
const Point = point.slice(0, 1).toUpperCase() + point.slice(1)
- const { value } = change
- const { document, selection, schema } = value
+ const { editor, value } = change
+ const { document, selection } = value
const p = selection[point]
- const hasVoidParent = document.hasVoidParent(p.path, schema)
+ const hasVoidParent = document.hasVoidParent(p.path, editor)
// what is this?
if (!hasVoidParent && p.offset - n >= 0) {
@@ -675,7 +675,7 @@ function pointBackward(change, point, n = 1) {
const block = document.getClosestBlock(p.path)
const isInBlock = block.hasNode(previous.key)
const isPreviousInVoid =
- previous && document.hasVoidParent(previous.key, schema)
+ previous && document.hasVoidParent(previous.key, editor)
change[`move${Point}ToEndOfNode`](previous)
// when is this called?
@@ -690,11 +690,11 @@ function pointForward(change, point, n = 1) {
if (n < 0) return pointBackward(change, point, -n)
const Point = point.slice(0, 1).toUpperCase() + point.slice(1)
- const { value } = change
- const { document, selection, schema } = value
+ const { editor, value } = change
+ const { document, selection } = value
const p = selection[point]
const text = document.getNode(p.path)
- const hasVoidParent = document.hasVoidParent(p.path, schema)
+ const hasVoidParent = document.hasVoidParent(p.path, editor)
// what is this?
if (!hasVoidParent && p.offset + n <= text.text.length) {
@@ -708,7 +708,7 @@ function pointForward(change, point, n = 1) {
const block = document.getClosestBlock(p.path)
const isInBlock = block.hasNode(next.key)
- const isNextInVoid = document.hasVoidParent(next.key, schema)
+ const isNextInVoid = document.hasVoidParent(next.key, editor)
change[`move${Point}ToStartOfNode`](next)
// when is this called?
@@ -718,4 +718,4 @@ function pointForward(change, point, n = 1) {
}
}
-export default Changes
+export default Commands
diff --git a/packages/slate/src/changes/on-value.js b/packages/slate/src/commands/on-value.js
similarity index 78%
rename from packages/slate/src/changes/on-value.js
rename to packages/slate/src/commands/on-value.js
index 197f48ecb..c3496da0e 100644
--- a/packages/slate/src/changes/on-value.js
+++ b/packages/slate/src/commands/on-value.js
@@ -1,12 +1,12 @@
import Value from '../models/value'
/**
- * Changes.
+ * Commands.
*
* @type {Object}
*/
-const Changes = {}
+const Commands = {}
/**
* Set `properties` on the value.
@@ -15,7 +15,7 @@ const Changes = {}
* @param {Object|Value} properties
*/
-Changes.setValue = (change, properties) => {
+Commands.setValue = (change, properties) => {
properties = Value.createProperties(properties)
const { value } = change
@@ -32,4 +32,4 @@ Changes.setValue = (change, properties) => {
* @type {Object}
*/
-export default Changes
+export default Commands
diff --git a/packages/slate/src/models/change.js b/packages/slate/src/controllers/change.js
similarity index 76%
rename from packages/slate/src/models/change.js
rename to packages/slate/src/controllers/change.js
index 4d3db0395..e16559142 100644
--- a/packages/slate/src/models/change.js
+++ b/packages/slate/src/controllers/change.js
@@ -1,10 +1,9 @@
import Debug from 'debug'
import isPlainObject from 'is-plain-object'
-import warning from 'slate-dev-warning'
+import warning from 'tiny-warning'
import { List } from 'immutable'
-import Changes from '../changes'
-import Operation from './operation'
+import Operation from '../models/operation'
import PathUtils from '../utils/path-utils'
/**
@@ -30,7 +29,8 @@ class Change {
*/
constructor(attrs) {
- const { value } = attrs
+ const { editor, value } = attrs
+ this.editor = editor
this.value = value
this.operations = new List()
@@ -52,8 +52,7 @@ class Change {
applyOperation(operation) {
const { operations } = this
- let { value } = this
- let { history } = value
+ let value = this.value
// Add in the current `value` in case the operation was serialized.
if (isPlainObject(operation)) {
@@ -62,26 +61,17 @@ class Change {
operation = Operation.create(operation)
- // Default options to the change-level flags, this allows for setting
- // specific options for all of the operations of a given change.
- let { merge, save } = this.tmp
-
- // If `merge` is non-commital, and this is not the first operation in a new change
- // then we should merge.
- if (merge == null && operations.size !== 0) {
- merge = true
- }
+ // Save the operation into the history. Since `save` is a command, we need
+ // to do it without normalizing, since it would have side effects.
+ this.withoutNormalizing(() => {
+ this.save(operation)
+ value = this.value
+ })
// Apply the operation to the value.
- debug('apply', { operation, save, merge })
+ debug('apply', { operation })
value = operation.apply(value)
- // If needed, save the operation to the history.
- if (history && save) {
- history = history.save(operation, { merge })
- value = value.set('history', history)
- }
-
// Get the paths of the affected nodes, and mark them as dirty.
const newDirtyPaths = getDirtyPaths(operation)
const dirty = this.tmp.dirty.reduce((memo, path) => {
@@ -103,12 +93,11 @@ class Change {
* Apply a series of `operations` to the current value.
*
* @param {Array|List} operations
- * @param {Object} options
* @return {Change}
*/
- applyOperations(operations, options) {
- operations.forEach(op => this.applyOperation(op, options))
+ applyOperations(operations) {
+ operations.forEach(op => this.applyOperation(op))
return this
}
@@ -126,6 +115,33 @@ class Change {
return this
}
+ /**
+ * Run a `command` with `args`.
+ *
+ * @param {String} command
+ * @param {Any} ...args
+ * @return {Change}
+ */
+
+ command(command, ...args) {
+ const { editor } = this
+ editor.command(command, ...args)
+ return this
+ }
+
+ /**
+ * Run a `query` with `args`.
+ *
+ * @param {String} query
+ * @param {Any} ...args
+ * @return {Change}
+ */
+
+ query(query, ...args) {
+ const { editor } = this
+ return editor.query(query, ...args)
+ }
+
/**
* Normalize all of the nodes in the document from scratch.
*
@@ -134,11 +150,19 @@ class Change {
normalize() {
const { value } = this
- const { document } = value
+ let { document } = value
const table = document.getKeysToPathsTable()
const paths = Object.values(table).map(PathUtils.create)
this.tmp.dirty = this.tmp.dirty.concat(paths)
this.normalizeDirtyPaths()
+
+ const { selection } = value
+ document = value.document
+
+ if (selection.isUnset && document.nodes.size) {
+ this.moveToStartOfDocument()
+ }
+
return this
}
@@ -162,26 +186,21 @@ class Change {
}
/**
- * Normalize the node at a specific `path`, iterating as many times as
- * necessary until it satisfies all of the schema rules.
+ * Normalize the node at a specific `path`.
*
* @param {Array} path
* @return {Change}
*/
normalizeNodeByPath(path) {
- const { value } = this
- let { document, schema } = value
+ const { editor, value } = this
+ let { document } = value
let node = document.assertNode(path)
-
let iterations = 0
- const max =
- schema.stack.plugins.length +
- schema.rules.length +
- (node.object === 'text' ? 1 : node.nodes.size)
+ const max = 1000 + (node.object === 'text' ? 1 : node.nodes.size)
const iterate = () => {
- const fn = node.normalize(schema)
+ const fn = node.normalize(editor)
if (!fn) return
// Run the normalize `fn` to fix the node.
@@ -247,46 +266,6 @@ class Change {
return this
}
- /**
- * Apply a series of changes inside a synchronous `fn`, without merging any of
- * the new operations into previous save point in the history.
- *
- * @param {Function} fn
- * @return {Change}
- */
-
- withoutMerging(fn) {
- const value = this.tmp.merge
- this.tmp.merge = false
- fn(this)
- this.tmp.merge = value
- return this
- }
-
- /**
- * Apply a series of changes inside a synchronous `fn`, without saving any of
- * their operations into the history.
- *
- * @param {Function} fn
- * @return {Change}
- */
-
- withoutSaving(fn) {
- const value = this.tmp.save
- this.tmp.save = false
- fn(this)
- this.tmp.save = value
- return this
- }
-
- /**
- * Set an operation flag by `key` to `value`.
- *
- * @param {String} key
- * @param {Any} value
- * @return {Change}
- */
-
/**
* Deprecated.
*/
@@ -399,18 +378,6 @@ function getDirtyPaths(operation) {
}
}
-/**
- * Add a change method for each of the changes.
- */
-
-Object.keys(Changes).forEach(type => {
- Change.prototype[type] = function(...args) {
- debug(type, { args })
- this.call(Changes[type], ...args)
- return this
- }
-})
-
/**
* Export.
*
diff --git a/packages/slate/src/controllers/editor.js b/packages/slate/src/controllers/editor.js
new file mode 100644
index 000000000..6088e1296
--- /dev/null
+++ b/packages/slate/src/controllers/editor.js
@@ -0,0 +1,333 @@
+import Debug from 'debug'
+import invariant from 'tiny-invariant'
+
+import AbstractChange from './change'
+import CorePlugin from '../plugins/core'
+import CommandsPlugin from '../plugins/commands'
+import QueriesPlugin from '../plugins/queries'
+import SchemaPlugin from '../plugins/schema'
+import Value from '../models/value'
+
+/**
+ * Debug.
+ *
+ * @type {Function}
+ */
+
+const debug = Debug('slate:editor')
+
+/**
+ * The core plugin.
+ *
+ * @type {Array|Object}
+ */
+
+const corePlugin = CorePlugin()
+
+/**
+ * Editor.
+ *
+ * @type {Editor}
+ */
+
+class Editor {
+ /**
+ * Create a new `Editor` with `attrs`.
+ *
+ * @param {Object} attrs
+ * @param {Object} options
+ */
+
+ constructor(attrs = {}, options = {}) {
+ const { editor = this } = options
+ const {
+ onChange = () => {},
+ plugins = [],
+ readOnly = false,
+ value = Value.create(),
+ } = attrs
+
+ this.Change = class Change extends AbstractChange {}
+ this.editor = editor
+ this.middleware = {}
+ this.onChange = onChange
+ this.readOnly = null
+ this.value = null
+
+ this.tmp = {
+ change: null,
+ isChanging: false,
+ }
+
+ registerPlugin(this, corePlugin)
+ plugins.forEach(p => registerPlugin(this, p))
+
+ this.run('onConstruct', this)
+
+ this.setReadOnly(readOnly)
+ this.setValue(value, options)
+ }
+
+ /**
+ * Perform a change on the editor, passing `...args` to `change.call`.
+ *
+ * @param {Any} ...args
+ */
+
+ change(...args) {
+ const { Change, editor, value } = this
+ const { isChanging } = this.tmp
+ const change = isChanging ? this.tmp.change : new Change({ value, editor })
+
+ try {
+ this.tmp.change = change
+ this.tmp.isChanging = true
+ change.call(...args)
+ } catch (error) {
+ throw error
+ } finally {
+ this.tmp.isChanging = isChanging
+ }
+
+ // If this isn't the top-most change function, exit to let it finish.
+ if (isChanging === true) {
+ return
+ }
+
+ // If the change doesn't define any operations to apply, abort.
+ if (change.operations.size === 0) {
+ return
+ }
+
+ this.run('onChange', change)
+
+ // Call the provided `onChange` handler.
+ this.value = change.value
+ this.onChange(change)
+ }
+
+ /**
+ * Trigger a `command` with `...args`.
+ *
+ * @param {String} command
+ * @param {Any} ...args
+ */
+
+ command(command, ...args) {
+ debug('command', { command, args })
+
+ this.change(change => {
+ const obj = { type: command, args }
+ this.run('onCommand', obj, change)
+ })
+ }
+
+ /**
+ * Process an `event` by running it through the stack.
+ *
+ * @param {String} handler
+ * @param {Event} event
+ */
+
+ event(handler, event) {
+ debug('event', { handler, event })
+
+ this.change(change => {
+ this.run(handler, event, change)
+ })
+ }
+
+ /**
+ * Ask a `query` with `...args`.
+ *
+ * @param {String} query
+ * @param {Any} ...args
+ */
+
+ query(query, ...args) {
+ debug('query', { query, args })
+
+ const obj = { type: query, args }
+ return this.run('onQuery', obj)
+ }
+
+ /**
+ * Register a `command` with the editor.
+ *
+ * @param {String} command
+ */
+
+ registerCommand(command) {
+ const { Change } = this
+ if (Change.prototype[command]) return
+
+ Change.prototype[command] = function(...args) {
+ const change = this.command(command, ...args)
+ return change
+ }
+ }
+
+ /**
+ * Register a `query` with the editor.
+ *
+ * @param {String} query
+ */
+
+ registerQuery(query) {
+ const { Change } = this
+ if (Change.prototype[query]) return
+
+ Change.prototype[query] = function(...args) {
+ const ret = this.query(query, ...args)
+ return ret
+ }
+ }
+
+ /**
+ * Run through the middleware stack by `key` with `args`.
+ *
+ * @param {String} key
+ * @param {Any} ...args
+ * @return {Any}
+ */
+
+ run(key, ...args) {
+ const middleware = this.middleware[key] || []
+ let i = 0
+
+ function next(...overrides) {
+ const fn = middleware[i++]
+ if (!fn) return
+
+ if (overrides.length) {
+ args = overrides
+ }
+
+ const ret = fn(...args, next)
+ return ret
+ }
+
+ Object.defineProperty(next, 'change', {
+ get() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `editor` is no longer passed as the third argument to event handlers. You can access it via `change.editor` instead.'
+ )
+ },
+ })
+
+ Object.defineProperty(next, 'onChange', {
+ get() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `editor` is no longer passed as the third argument to event handlers. You can access it via `change.editor` instead.'
+ )
+ },
+ })
+
+ Object.defineProperty(next, 'props', {
+ get() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `editor` is no longer passed as the third argument to event handlers. You can access it via `change.editor` instead.'
+ )
+ },
+ })
+
+ Object.defineProperty(next, 'schema', {
+ get() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `editor` is no longer passed as the third argument to event handlers. You can access it via `change.editor` instead.'
+ )
+ },
+ })
+
+ Object.defineProperty(next, 'stack', {
+ get() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `editor` is no longer passed as the third argument to event handlers. You can access it via `change.editor` instead.'
+ )
+ },
+ })
+
+ return next()
+ }
+
+ /**
+ * Set the `readOnly` flag.
+ *
+ * @param {Boolean} readOnly
+ * @return {Editor}
+ */
+
+ setReadOnly(readOnly) {
+ this.readOnly = readOnly
+ return this
+ }
+
+ /**
+ * Set the editor's `value`.
+ *
+ * @param {Value} value
+ * @param {Options} options
+ * @return {Editor}
+ */
+
+ setValue(value, options = {}) {
+ const { normalize = value !== this.value } = options
+ this.value = value
+
+ if (normalize) {
+ this.change(change => change.normalize())
+ }
+
+ return this
+ }
+}
+
+/**
+ * Register a `plugin` with the editor.
+ *
+ * @param {Editor} editor
+ * @param {Object|Array} plugin
+ */
+
+function registerPlugin(editor, plugin) {
+ if (Array.isArray(plugin)) {
+ plugin.forEach(p => registerPlugin(editor, p))
+ return
+ }
+
+ const { commands, queries, schema, ...rest } = plugin
+
+ if (commands) {
+ const commandsPlugin = CommandsPlugin({ commands })
+ registerPlugin(editor, commandsPlugin)
+ }
+
+ if (queries) {
+ const queriesPlugin = QueriesPlugin({ queries })
+ registerPlugin(editor, queriesPlugin)
+ }
+
+ if (schema) {
+ const schemaPlugin = SchemaPlugin(schema)
+ registerPlugin(editor, schemaPlugin)
+ }
+
+ for (const key in rest) {
+ const fn = rest[key]
+ const middleware = (editor.middleware[key] = editor.middleware[key] || [])
+ middleware.push(fn)
+ }
+}
+
+/**
+ * Export.
+ *
+ * @type {Editor}
+ */
+
+export default Editor
diff --git a/packages/slate/src/index.js b/packages/slate/src/index.js
index 37a7603e2..cc44ec829 100644
--- a/packages/slate/src/index.js
+++ b/packages/slate/src/index.js
@@ -5,25 +5,21 @@ import './interfaces/element'
import './interfaces/range'
import Block from './models/block'
-import Change from './models/change'
-import Changes from './changes'
+import Change from './controllers/change'
import Data from './models/data'
import Decoration from './models/decoration'
import Document from './models/document'
-import History from './models/history'
+import Editor from './controllers/editor'
import Inline from './models/inline'
import KeyUtils from './utils/key-utils'
import Leaf from './models/leaf'
import Mark from './models/mark'
import Node from './models/node'
import Operation from './models/operation'
-import Operations from './operations'
import PathUtils from './utils/path-utils'
import Point from './models/point'
import Range from './models/range'
-import Schema from './models/schema'
import Selection from './models/selection'
-import Stack from './models/stack'
import Text from './models/text'
import TextUtils from './utils/text-utils'
import Value from './models/value'
@@ -38,25 +34,21 @@ import { resetMemoization, useMemoization } from './utils/memoize'
export {
Block,
Change,
- Changes,
Data,
Decoration,
Document,
- History,
+ Editor,
Inline,
KeyUtils,
Leaf,
Mark,
Node,
Operation,
- Operations,
PathUtils,
Point,
Range,
resetMemoization,
- Schema,
Selection,
- Stack,
Text,
TextUtils,
useMemoization,
@@ -65,25 +57,22 @@ export {
export default {
Block,
- Changes,
+ Change,
Data,
Decoration,
Document,
- History,
+ Editor,
Inline,
KeyUtils,
Leaf,
Mark,
Node,
Operation,
- Operations,
PathUtils,
Point,
Range,
resetMemoization,
- Schema,
Selection,
- Stack,
Text,
TextUtils,
useMemoization,
diff --git a/packages/slate/src/interfaces/element.js b/packages/slate/src/interfaces/element.js
index 5ef55b7d9..fbcdb7c35 100644
--- a/packages/slate/src/interfaces/element.js
+++ b/packages/slate/src/interfaces/element.js
@@ -1,4 +1,5 @@
import direction from 'direction'
+import invariant from 'tiny-invariant'
import { List, OrderedSet, Set } from 'immutable'
import mixin from '../utils/mixin'
@@ -11,6 +12,7 @@ import PathUtils from '../utils/path-utils'
import Point from '../models/point'
import Range from '../models/range'
import Selection from '../models/selection'
+import Value from '../models/value'
/**
* The interface that `Document`, `Block` and `Inline` all implement, to make
@@ -398,15 +400,20 @@ class ElementInterface {
* Get the closest void parent of a node by `path`.
*
* @param {List|String} path
- * @param {Schema} schema
+ * @param {Editor} editor
* @return {Node|Null}
*/
- getClosestVoid(path, schema) {
+ getClosestVoid(path, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `node.getClosestVoid` method takes an `editor` instead of a `value`.'
+ )
+
const ancestors = this.getAncestors(path)
if (!ancestors) return null
- const ancestor = ancestors.findLast(a => schema.isVoid(a))
+ const ancestor = ancestors.findLast(a => editor.query('isVoid', a))
return ancestor
}
@@ -429,18 +436,21 @@ class ElementInterface {
}
/**
- * Get the decorations for the node from a `stack`.
+ * Get the decorations for the node from an `editor`.
*
- * @param {Stack} stack
+ * @param {Editor} editor
* @return {List}
*/
- getDecorations(stack) {
- const allDecorations = stack
- .map('decorateNode', this)
- .map(decorations => Decoration.createList(decorations))
- const list = List(allDecorations).flatten(true)
- return list
+ getDecorations(editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `node.getDecorations` method takes an `editor` instead of a `value`.'
+ )
+
+ const array = editor.run('decorateNode', this) || []
+ const decorations = Decoration.createList(array)
+ return decorations
}
/**
@@ -1359,12 +1369,17 @@ class ElementInterface {
* Check if a node has a void parent.
*
* @param {List|String} path
- * @param {Schema} schema
+ * @param {Editor} editor
* @return {Boolean}
*/
- hasVoidParent(path, schema) {
- const closest = this.getClosestVoid(path, schema)
+ hasVoidParent(path, editor) {
+ invariant(
+ !Value.isValue(editor),
+ 'As of Slate 0.42.0, the `node.hasVoidParent` method takes an `editor` instead of a `value`.'
+ )
+
+ const closest = this.getClosestVoid(path, editor)
return !!closest
}
diff --git a/packages/slate/src/interfaces/model.js b/packages/slate/src/interfaces/model.js
index 0ac6f60b2..c93d0fe59 100644
--- a/packages/slate/src/interfaces/model.js
+++ b/packages/slate/src/interfaces/model.js
@@ -1,9 +1,7 @@
import mixin from '../utils/mixin'
import Block from '../models/block'
-import Change from '../models/change'
import Decoration from '../models/decoration'
import Document from '../models/document'
-import History from '../models/history'
import Inline from '../models/inline'
import Leaf from '../models/leaf'
import Mark from '../models/mark'
@@ -11,9 +9,7 @@ import Node from '../models/node'
import Operation from '../models/operation'
import Point from '../models/point'
import Range from '../models/range'
-import Schema from '../models/schema'
import Selection from '../models/selection'
-import Stack from '../models/stack'
import Text from '../models/text'
import Value from '../models/value'
@@ -49,10 +45,8 @@ class ModelInterface {
mixin(ModelInterface, [
Block,
- Change,
Decoration,
Document,
- History,
Inline,
Leaf,
Mark,
@@ -60,9 +54,7 @@ mixin(ModelInterface, [
Operation,
Point,
Range,
- Schema,
Selection,
- Stack,
Text,
Value,
])
diff --git a/packages/slate/src/interfaces/node.js b/packages/slate/src/interfaces/node.js
index 9bd80d365..9823ef20e 100644
--- a/packages/slate/src/interfaces/node.js
+++ b/packages/slate/src/interfaces/node.js
@@ -1,4 +1,4 @@
-import warning from 'slate-dev-warning'
+import warning from 'tiny-warning'
import { List } from 'immutable'
import mixin from '../utils/mixin'
@@ -28,28 +28,6 @@ class NodeInterface {
return this.getText()
}
- /**
- * Check whether the node is a leaf inline.
- *
- * @return {Boolean}
- */
-
- getFirstInvalidNode(schema) {
- if (this.object === 'text') {
- const invalid = this.validate(schema) ? this : null
- return invalid
- }
-
- let invalid = null
-
- this.nodes.find(n => {
- invalid = n.validate(schema) ? n : n.getFirstInvalidNode(schema)
- return invalid
- })
-
- return invalid
- }
-
/**
* Get the first text node of a node, or the node itself.
*
@@ -181,14 +159,14 @@ class NodeInterface {
}
/**
- * Normalize the text node with a `schema`.
+ * Normalize the text node with an `editor`.
*
- * @param {Schema} schema
+ * @param {Editor} editor
* @return {Function|Void}
*/
- normalize(schema) {
- const normalizer = schema.normalizeNode(this)
+ normalize(editor) {
+ const normalizer = editor.run('normalizeNode', this)
return normalizer
}
@@ -232,14 +210,14 @@ class NodeInterface {
}
/**
- * Validate the node against a `schema`.
+ * Validate the node with an `editor`.
*
- * @param {Schema} schema
+ * @param {Editor} editor
* @return {Error|Void}
*/
- validate(schema) {
- const error = schema.validateNode(this)
+ validate(editor) {
+ const error = editor.run('validateNode', this)
return error
}
}
@@ -249,7 +227,6 @@ class NodeInterface {
*/
memoize(NodeInterface.prototype, [
- 'getFirstInvalidNode',
'getFirstText',
'getKeysToPathsTable',
'getLastText',
diff --git a/packages/slate/src/interfaces/object.js b/packages/slate/src/interfaces/object.js
index 487c49210..8d65d6c90 100644
--- a/packages/slate/src/interfaces/object.js
+++ b/packages/slate/src/interfaces/object.js
@@ -1,8 +1,8 @@
import Block from '../models/block'
-import Change from '../models/change'
+import Change from '../controllers/change'
import Decoration from '../models/decoration'
import Document from '../models/document'
-import History from '../models/history'
+import Editor from '../controllers/editor'
import Inline from '../models/inline'
import Leaf from '../models/leaf'
import Mark from '../models/mark'
@@ -10,9 +10,7 @@ import Node from '../models/node'
import Operation from '../models/operation'
import Point from '../models/point'
import Range from '../models/range'
-import Schema from '../models/schema'
import Selection from '../models/selection'
-import Stack from '../models/stack'
import Text from '../models/text'
import Value from '../models/value'
import isObject, { TYPES } from '../utils/is-object'
@@ -54,7 +52,7 @@ mixin(create('block'), [Block])
mixin(create('change'), [Change])
mixin(create('decoration'), [Decoration])
mixin(create('document'), [Document])
-mixin(create('history'), [History])
+mixin(create('editor'), [Editor])
mixin(create('inline'), [Inline])
mixin(create('leaf'), [Leaf])
mixin(create('mark'), [Mark])
@@ -62,8 +60,6 @@ mixin(create('node'), [Node])
mixin(create('operation'), [Operation])
mixin(create('point'), [Point])
mixin(create('range'), [Range])
-mixin(create('schema'), [Schema])
mixin(create('selection'), [Selection])
-mixin(create('stack'), [Stack])
mixin(create('text'), [Text])
mixin(create('value'), [Value])
diff --git a/packages/slate/src/models/history.js b/packages/slate/src/models/history.js
deleted file mode 100644
index 49e8bc9a7..000000000
--- a/packages/slate/src/models/history.js
+++ /dev/null
@@ -1,187 +0,0 @@
-import Debug from 'debug'
-import isPlainObject from 'is-plain-object'
-import { List, Record, Stack } from 'immutable'
-
-/**
- * Debug.
- *
- * @type {Function}
- */
-
-const debug = Debug('slate:history')
-
-/**
- * Default properties.
- *
- * @type {Object}
- */
-
-const DEFAULTS = {
- redos: undefined,
- undos: undefined,
-}
-
-/**
- * History.
- *
- * @type {History}
- */
-
-class History extends Record(DEFAULTS) {
- /**
- * Create a new `History` with `attrs`.
- *
- * @param {Object|History} attrs
- * @return {History}
- */
-
- static create(attrs = {}) {
- if (History.isHistory(attrs)) {
- return attrs
- }
-
- if (isPlainObject(attrs)) {
- return History.fromJSON(attrs)
- }
-
- throw new Error(
- `\`History.create\` only accepts objects or histories, but you passed it: ${attrs}`
- )
- }
-
- /**
- * Create a list of `Operations` from `operations`.
- *
- * @param {Array|List} operations
- * @return {List}
- */
-
- static createOperationsList(operations = []) {
- if (List.isList(operations)) {
- return operations
- }
-
- if (Array.isArray(operations)) {
- return new List(operations)
- }
-
- throw new Error(
- `\`History.createList\` only accepts arrays or lists, but you passed it: ${operations}`
- )
- }
-
- /**
- * Create a `History` from a JSON `object`.
- *
- * @param {Object} object
- * @return {History}
- */
-
- static fromJSON(object) {
- const { redos = [], undos = [] } = object
-
- const history = new History({
- redos: new Stack(redos.map(this.createOperationsList)),
- undos: new Stack(undos.map(this.createOperationsList)),
- })
-
- return history
- }
-
- /**
- * Save an `operation` into the history.
- *
- * @param {Object} operation
- * @param {Object} options
- * @return {History}
- */
-
- save(operation, options = {}) {
- let history = this
- let { undos, redos } = history
- let { merge, skip } = options
-
- if (skip) {
- return history
- }
-
- const prevBatch = undos.peek()
- const prevOperation = prevBatch && prevBatch.last()
-
- if (merge == null) {
- merge = shouldMerge(operation, prevOperation)
- }
-
- debug('save', { operation, merge })
-
- // If the `merge` flag is true, add the operation to the previous batch.
- if (merge && prevBatch) {
- const batch = prevBatch.push(operation)
- undos = undos.pop()
- undos = undos.push(batch)
- } else {
- // Otherwise, create a new batch with the operation.
- const batch = new List([operation])
- undos = undos.push(batch)
- }
-
- // Constrain the history to 100 entries for memory's sake.
- if (undos.size > 100) {
- undos = undos.take(100)
- }
-
- // Clear the redos and update the history.
- redos = redos.clear()
- history = history.set('undos', undos).set('redos', redos)
- return history
- }
-
- /**
- * Return a JSON representation of the history.
- *
- * @return {Object}
- */
-
- toJSON() {
- const object = {
- object: this.object,
- redos: this.redos.toJSON(),
- undos: this.undos.toJSON(),
- }
-
- return object
- }
-}
-
-/**
- * Check whether to merge a new operation `o` into the previous operation `p`.
- *
- * @param {Object} o
- * @param {Object} p
- * @return {Boolean}
- */
-
-function shouldMerge(o, p) {
- if (!p) return false
-
- const merge =
- (o.type == 'set_selection' && p.type == 'set_selection') ||
- (o.type == 'insert_text' &&
- p.type == 'insert_text' &&
- o.offset == p.offset + p.text.length &&
- o.path.equals(p.path)) ||
- (o.type == 'remove_text' &&
- p.type == 'remove_text' &&
- o.offset + o.text.length == p.offset &&
- o.path.equals(p.path))
-
- return merge
-}
-
-/**
- * Export.
- *
- * @type {History}
- */
-
-export default History
diff --git a/packages/slate/src/models/leaf.js b/packages/slate/src/models/leaf.js
index 5ba1e2149..9923e1d61 100644
--- a/packages/slate/src/models/leaf.js
+++ b/packages/slate/src/models/leaf.js
@@ -244,6 +244,20 @@ class Leaf extends Record(DEFAULTS) {
return this.set('marks', marks.union(set))
}
+ /**
+ * Insert a text `string` into the leaf at `offset`.
+ *
+ * @param {Number} offset
+ * @param {String} string
+ * @return {Leaf}
+ */
+
+ insertText(offset, string) {
+ const { text } = this
+ const next = text.slice(0, offset) + string + text.slice(offset)
+ return this.set('text', next)
+ }
+
/**
* Remove a `mark` from the leaf.
*
diff --git a/packages/slate/src/models/node.js b/packages/slate/src/models/node.js
index 84db44de0..bb3c7060f 100644
--- a/packages/slate/src/models/node.js
+++ b/packages/slate/src/models/node.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import warning from 'slate-dev-warning'
+import warning from 'tiny-warning'
import { List } from 'immutable'
import Block from './block'
diff --git a/packages/slate/src/models/operation.js b/packages/slate/src/models/operation.js
index 07ce8c18f..df4769683 100644
--- a/packages/slate/src/models/operation.js
+++ b/packages/slate/src/models/operation.js
@@ -293,7 +293,6 @@ class Operation extends Record(DEFAULTS) {
const v = {}
if ('data' in value) v.data = value.data.toJS()
if ('decorations' in value) v.decorations = value.decorations.toJS()
- if ('schema' in value) v.schema = value.schema.toJS()
value = v
}
diff --git a/packages/slate/src/models/point.js b/packages/slate/src/models/point.js
index 1f0b59c42..79878407e 100644
--- a/packages/slate/src/models/point.js
+++ b/packages/slate/src/models/point.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import warning from 'slate-dev-warning'
+import warning from 'tiny-warning'
import { Record } from 'immutable'
import KeyUtils from '../utils/key-utils'
diff --git a/packages/slate/src/models/stack.js b/packages/slate/src/models/stack.js
deleted file mode 100644
index 7384d435d..000000000
--- a/packages/slate/src/models/stack.js
+++ /dev/null
@@ -1,129 +0,0 @@
-import { Record } from 'immutable'
-
-import memoize from '../utils/memoize'
-
-/**
- * Default properties.
- *
- * @type {Object}
- */
-
-const DEFAULTS = {
- plugins: undefined,
-}
-
-/**
- * Stack.
- *
- * @type {Stack}
- */
-
-class Stack extends Record(DEFAULTS) {
- /**
- * Constructor.
- *
- * @param {Object} attrs
- */
-
- static create(attrs = {}) {
- const { plugins = [] } = attrs
- const stack = new Stack({ plugins })
- return stack
- }
-
- /**
- * Get all plugins with `property`.
- *
- * @param {String} property
- * @return {Array}
- */
-
- getPluginsWith(property) {
- return this.plugins.filter(plugin => plugin[property] != null)
- }
-
- /**
- * Iterate the plugins with `property`, returning the first non-null value.
- *
- * @param {String} property
- * @param {Any} ...args
- */
-
- find(property, ...args) {
- const plugins = this.getPluginsWith(property)
-
- for (const plugin of plugins) {
- const ret = plugin[property](...args)
- if (ret != null) return ret
- }
- }
-
- /**
- * Iterate the plugins with `property`, returning all the non-null values.
- *
- * @param {String} property
- * @param {Any} ...args
- * @return {Array}
- */
-
- map(property, ...args) {
- const plugins = this.getPluginsWith(property)
- const array = []
-
- for (const plugin of plugins) {
- const ret = plugin[property](...args)
- if (ret != null) array.push(ret)
- }
-
- return array
- }
-
- /**
- * Iterate the plugins with `property`, breaking on any a non-null values.
- *
- * @param {String} property
- * @param {Any} ...args
- */
-
- run(property, ...args) {
- const plugins = this.getPluginsWith(property)
-
- for (const plugin of plugins) {
- const ret = plugin[property](...args)
- if (ret != null) return
- }
- }
-
- /**
- * Iterate the plugins with `property`, reducing to a set of React children.
- *
- * @param {String} property
- * @param {Object} props
- * @param {Any} ...args
- */
-
- render(property, props, ...args) {
- const plugins = this.getPluginsWith(property)
- return plugins.reduceRight((children, plugin) => {
- if (!plugin[property]) return children
- const ret = plugin[property](props, ...args)
- if (ret == null) return children
- props.children = ret
- return ret
- }, props.children === undefined ? null : props.children)
- }
-}
-
-/**
- * Memoize read methods.
- */
-
-memoize(Stack.prototype, ['getPluginsWith'])
-
-/**
- * Export.
- *
- * @type {Stack}
- */
-
-export default Stack
diff --git a/packages/slate/src/models/text.js b/packages/slate/src/models/text.js
index 3754560b8..8ba59e46f 100644
--- a/packages/slate/src/models/text.js
+++ b/packages/slate/src/models/text.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import warning from 'slate-dev-warning'
+import warning from 'tiny-warning'
import { List, OrderedSet, Record, Set } from 'immutable'
import Leaf from './leaf'
@@ -609,8 +609,8 @@ class Text extends Record(DEFAULTS) {
/**
* Set leaves with normalized `leaves`
*
- * @param {Schema} schema
- * @returns {Text|Null}
+ * @param {List} leaves
+ * @returns {Text}
*/
setLeaves(leaves) {
diff --git a/packages/slate/src/models/value.js b/packages/slate/src/models/value.js
index f0b1155bb..80da34f47 100644
--- a/packages/slate/src/models/value.js
+++ b/packages/slate/src/models/value.js
@@ -1,13 +1,11 @@
import isPlainObject from 'is-plain-object'
+import invariant from 'tiny-invariant'
import { Record, Set, List } from 'immutable'
import PathUtils from '../utils/path-utils'
-import Change from './change'
import Data from './data'
import Decoration from './decoration'
import Document from './document'
-import History from './history'
-import Schema from './schema'
/**
* Default properties.
@@ -19,8 +17,6 @@ const DEFAULTS = {
data: undefined,
decorations: undefined,
document: undefined,
- history: undefined,
- schema: undefined,
selection: undefined,
}
@@ -65,7 +61,6 @@ class Value extends Record(DEFAULTS) {
return {
data: a.data,
decorations: a.decorations,
- schema: a.schema,
}
}
@@ -74,7 +69,6 @@ class Value extends Record(DEFAULTS) {
if ('data' in a) p.data = Data.create(a.data)
if ('decorations' in a)
p.decorations = Decoration.createList(a.decorations)
- if ('schema' in a) p.schema = Schema.create(a.schema)
return p
}
@@ -94,18 +88,8 @@ class Value extends Record(DEFAULTS) {
*/
static fromJSON(object, options = {}) {
- let {
- data = {},
- decorations = [],
- document = {},
- selection = {},
- schema = {},
- history = {},
- } = object
-
+ let { data = {}, decorations = [], document = {}, selection = {} } = object
data = Data.fromJSON(data)
- schema = Schema.fromJSON(schema)
- history = History.fromJSON(history)
document = Document.fromJSON(document)
selection = document.createSelection(selection)
decorations = List(decorations.map(d => Decoration.fromJSON(d)))
@@ -116,21 +100,13 @@ class Value extends Record(DEFAULTS) {
selection = document.createSelection(selection)
}
- let value = new Value({
+ const value = new Value({
data,
decorations,
document,
selection,
- schema,
- history,
})
- if (options.normalize !== false) {
- const change = value.change()
- change.withoutSaving(() => change.normalize())
- value = change.value
- }
-
return value
}
@@ -441,17 +417,6 @@ class Value extends Record(DEFAULTS) {
: this.document.getTextsAtRange(this.selection)
}
- /**
- * Create a new `Change` with the current value as a starting point.
- *
- * @param {Object} attrs
- * @return {Change}
- */
-
- change(attrs = {}) {
- return new Change({ ...attrs, value: this })
- }
-
/**
* Add mark to text at `offset` and `length` in node by `path`.
*
@@ -503,38 +468,19 @@ class Value extends Record(DEFAULTS) {
insertText(path, offset, text, marks) {
let value = this
- let { document, schema } = value
+ let { document } = value
+ const node = document.assertNode(path)
document = document.insertText(path, offset, text, marks)
value = value.set('document', document)
- // Update any ranges that were affected.
- const node = document.assertNode(path)
-
value = value.mapRanges(range => {
- const { anchor, focus, isBackward } = range
- const isAtomic =
- Decoration.isDecoration(range) && schema.isAtomic(range.mark)
-
- if (
- anchor.key === node.key &&
- (anchor.offset > offset ||
- (anchor.offset === offset && (!isAtomic || !isBackward)))
- ) {
- range = range.moveAnchorForward(text.length)
- }
-
- if (
- focus.key === node.key &&
- (focus.offset > offset ||
- (focus.offset == offset && (!isAtomic || isBackward)))
- ) {
- range = range.moveFocusForward(text.length)
- }
-
- return range
+ return range.updatePoints(point => {
+ return point.key === node.key && point.offset >= offset
+ ? point.setOffset(point.offset + text.length)
+ : point
+ })
})
- value = value.clearAtomicRanges(node.key, offset)
return value
}
@@ -673,37 +619,30 @@ class Value extends Record(DEFAULTS) {
removeText(path, offset, text) {
let value = this
let { document } = value
+ const node = document.assertNode(path)
document = document.removeText(path, offset, text)
value = value.set('document', document)
- const node = document.assertNode(path)
const { length } = text
- const rangeOffset = offset + length
-
- value = value.clearAtomicRanges(node.key, offset, offset + length)
+ const start = offset
+ const end = offset + length
value = value.mapRanges(range => {
- const { anchor, focus } = range
+ return range.updatePoints(point => {
+ if (point.key !== node.key) {
+ return point
+ }
- if (anchor.key === node.key) {
- range =
- anchor.offset >= rangeOffset
- ? range.moveAnchorBackward(length)
- : anchor.offset > offset
- ? range.moveAnchorTo(anchor.key, offset)
- : range
- }
+ if (point.offset >= end) {
+ return point.setOffset(point.offset - length)
+ }
- if (focus.key === node.key) {
- range =
- focus.offset >= rangeOffset
- ? range.moveFocusBackward(length)
- : focus.offset > offset
- ? range.moveFocusTo(focus.key, offset)
- : range
- }
+ if (point.offset > start) {
+ return point.setOffset(start)
+ }
- return range
+ return point
+ })
})
return value
@@ -754,21 +693,13 @@ class Value extends Record(DEFAULTS) {
setProperties(properties) {
let value = this
const { document } = value
- const { data, decorations, history, schema } = properties
+ const { data, decorations } = properties
const props = {}
if (data) {
props.data = data
}
- if (history) {
- props.history = history
- }
-
- if (schema) {
- props.schema = schema
- }
-
if (decorations) {
props.decorations = decorations.map(d => {
return d.isSet ? d : document.resolveDecoration(d)
@@ -862,44 +793,6 @@ class Value extends Record(DEFAULTS) {
return value
}
- /**
- * Remove any atomic ranges inside a `key`, `offset` and `length`.
- *
- * @param {String} key
- * @param {Number} from
- * @param {Number?} to
- * @return {Value}
- */
-
- clearAtomicRanges(key, from, to = null) {
- let value = this
- const { schema } = value
-
- value = this.mapRanges(range => {
- if (!Decoration.isDecoration(range)) return range
- const { start, end, mark } = range
- const isAtomic = schema.isAtomic(mark)
- if (!isAtomic) return range
- if (start.key !== key) return range
-
- if (start.offset < from && (end.key !== key || end.offset > from)) {
- return null
- }
-
- if (
- to != null &&
- start.offset < to &&
- (end.key !== key || end.offset > to)
- ) {
- return null
- }
-
- return range
- })
-
- return value
- }
-
/**
* Return a JSON representation of the value.
*
@@ -923,20 +816,30 @@ class Value extends Record(DEFAULTS) {
.map(d => d.toJSON(options))
}
- if (options.preserveHistory) {
- object.history = this.history.toJSON(options)
- }
-
if (options.preserveSelection) {
object.selection = this.selection.toJSON(options)
}
- if (options.preserveSchema) {
- object.schema = this.schema.toJSON(options)
- }
-
return object
}
+
+ /**
+ * Deprecated.
+ */
+
+ get history() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, the `value.history` model no longer exists, and the history is stored in `value.data` instead using plugins.'
+ )
+ }
+
+ change() {
+ invariant(
+ false,
+ 'As of Slate 0.42.0, value object are no longer schema-aware, and the `value.change()` method is no longer available. Use the `editor.change()` method on the new `Editor` controller instead.'
+ )
+ }
}
/**
diff --git a/packages/slate/src/plugins/commands.js b/packages/slate/src/plugins/commands.js
new file mode 100644
index 000000000..3c398f016
--- /dev/null
+++ b/packages/slate/src/plugins/commands.js
@@ -0,0 +1,72 @@
+/**
+ * A plugin that adds a set of commands to the editor.
+ *
+ * @param {Object} options
+ * @return {Object}
+ */
+
+function CommandsPlugin(options = {}) {
+ const { commands, defer = false } = options
+
+ if (!commands) {
+ throw new Error(
+ 'You must pass in the `commands` option to the Slate commands plugin.'
+ )
+ }
+
+ /**
+ * On command, if it exists in our list of commands, call it.
+ *
+ * @param {Object} command
+ * @param {Change} change
+ * @param {Function} next
+ */
+
+ function onCommand(command, change, next) {
+ const { type, args } = command
+ const fn = commands[type]
+ if (!fn) return next()
+
+ if (defer) {
+ const ret = next()
+ if (ret !== undefined) return ret
+ }
+
+ change.call(fn, ...args)
+ return true
+ }
+
+ /**
+ * On construct, register all the commands.
+ *
+ * @param {Editor} editor
+ * @param {Function} next
+ */
+
+ function onConstruct(editor, next) {
+ for (const command in commands) {
+ editor.registerCommand(command)
+ }
+
+ return next()
+ }
+
+ /**
+ * Return the plugin.
+ *
+ * @type {Object}
+ */
+
+ return {
+ onCommand,
+ onConstruct,
+ }
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default CommandsPlugin
diff --git a/packages/slate/src/plugins/core.js b/packages/slate/src/plugins/core.js
new file mode 100644
index 000000000..f32c8f08e
--- /dev/null
+++ b/packages/slate/src/plugins/core.js
@@ -0,0 +1,192 @@
+import AtCurrentRange from '../commands/at-current-range'
+import AtRange from '../commands/at-range'
+import ByPath from '../commands/by-path'
+import Commands from './commands'
+import OnHistory from '../commands/on-history'
+import OnSelection from '../commands/on-selection'
+import OnValue from '../commands/on-value'
+import Queries from './queries'
+import Schema from './schema'
+import Text from '../models/text'
+
+/**
+ * A plugin that defines the core Slate logic.
+ *
+ * @return {Object}
+ */
+
+function CorePlugin() {
+ /**
+ * The core Slate commands.
+ *
+ * @type {Object}
+ */
+
+ const commands = Commands({
+ defer: true,
+ commands: {
+ ...AtCurrentRange,
+ ...AtRange,
+ ...ByPath,
+ ...OnHistory,
+ ...OnSelection,
+ ...OnValue,
+ },
+ })
+
+ /**
+ * The core Slate queries.
+ *
+ * @type {Object}
+ */
+
+ const queries = Queries({
+ defer: true,
+ queries: {
+ isAtomic: () => false,
+ isVoid: () => false,
+ normalizeNode: () => {},
+ validateNode: () => {},
+ },
+ })
+
+ /**
+ * The core Slate schema.
+ *
+ * @type {Object}
+ */
+
+ const schema = Schema({
+ rules: [
+ // Only allow block nodes in documents.
+ {
+ match: { object: 'document' },
+ nodes: [
+ {
+ match: { object: 'block' },
+ },
+ ],
+ },
+
+ // Only allow block nodes or inline and text nodes in blocks.
+ {
+ match: {
+ object: 'block',
+ first: { object: 'block' },
+ },
+ nodes: [
+ {
+ match: { object: 'block' },
+ },
+ ],
+ },
+ {
+ match: {
+ object: 'block',
+ first: [{ object: 'inline' }, { object: 'text' }],
+ },
+ nodes: [
+ {
+ match: [{ object: 'inline' }, { object: 'text' }],
+ },
+ ],
+ },
+
+ // Only allow inline and text nodes in inlines.
+ {
+ match: { object: 'inline' },
+ nodes: [{ match: [{ object: 'inline' }, { object: 'text' }] }],
+ },
+
+ // Ensure that block and inline nodes have at least one text child.
+ {
+ match: [{ object: 'block' }, { object: 'inline' }],
+ nodes: [{ min: 1 }],
+ normalize: (change, error) => {
+ const { code, node } = error
+
+ if (code === 'child_required') {
+ change.insertNodeByKey(node.key, 0, Text.create())
+ }
+ },
+ },
+
+ // Ensure that inline nodes are surrounded by text nodes.
+ {
+ match: { object: 'block' },
+ first: [{ object: 'block' }, { object: 'text' }],
+ last: [{ object: 'block' }, { object: 'text' }],
+ normalize: (change, error) => {
+ const { code, node } = error
+ const text = Text.create()
+ let i
+
+ if (code === 'first_child_object_invalid') {
+ i = 0
+ } else if (code === 'last_child_object_invalid') {
+ i = node.nodes.size
+ } else {
+ return
+ }
+
+ change.insertNodeByKey(node.key, i, text)
+ },
+ },
+ {
+ match: { object: 'inline' },
+ first: [{ object: 'block' }, { object: 'text' }],
+ last: [{ object: 'block' }, { object: 'text' }],
+ previous: [{ object: 'block' }, { object: 'text' }],
+ next: [{ object: 'block' }, { object: 'text' }],
+ normalize: (change, error) => {
+ const { code, node, index } = error
+ const text = Text.create()
+ let i
+
+ if (code === 'first_child_object_invalid') {
+ i = 0
+ } else if (code === 'last_child_object_invalid') {
+ i = node.nodes.size
+ } else if (code === 'previous_sibling_object_invalid') {
+ i = index
+ } else if (code === 'next_sibling_object_invalid') {
+ i = index + 1
+ } else {
+ return
+ }
+
+ change.insertNodeByKey(node.key, i, text)
+ },
+ },
+
+ // Merge adjacent text nodes.
+ {
+ match: { object: 'text' },
+ next: [{ object: 'block' }, { object: 'inline' }],
+ normalize: (change, error) => {
+ const { code, next } = error
+
+ if (code === 'next_sibling_object_invalid') {
+ change.mergeNodeByKey(next.key)
+ }
+ },
+ },
+ ],
+ })
+
+ /**
+ * Return the plugins.
+ *
+ * @type {Array}
+ */
+
+ return [commands, queries, schema]
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default CorePlugin
diff --git a/packages/slate/src/plugins/queries.js b/packages/slate/src/plugins/queries.js
new file mode 100644
index 000000000..2aa4310ce
--- /dev/null
+++ b/packages/slate/src/plugins/queries.js
@@ -0,0 +1,71 @@
+/**
+ * A plugin that adds a set of queries to the editor.
+ *
+ * @param {Object} options
+ * @return {Object}
+ */
+
+function QueriesPlugin(options = {}) {
+ const { queries, defer = false } = options
+
+ if (!queries) {
+ throw new Error(
+ 'You must pass in the `queries` option to the Slate queries plugin.'
+ )
+ }
+
+ /**
+ * On construct, register all the queries.
+ *
+ * @param {Editor} editor
+ * @param {Function} next
+ */
+
+ function onConstruct(editor, next) {
+ for (const query in queries) {
+ editor.registerQuery(query)
+ }
+
+ return next()
+ }
+
+ /**
+ * On query, if it exists in our list of queries, call it.
+ *
+ * @param {Object} query
+ * @param {Function} next
+ */
+
+ function onQuery(query, next) {
+ const { type, args } = query
+ const fn = queries[type]
+ if (!fn) return next()
+
+ if (defer) {
+ const ret = next()
+ if (ret !== undefined) return ret
+ }
+
+ const ret = fn(...args)
+ return ret === undefined ? next() : ret
+ }
+
+ /**
+ * Return the plugin.
+ *
+ * @type {Object}
+ */
+
+ return {
+ onConstruct,
+ onQuery,
+ }
+}
+
+/**
+ * Export.
+ *
+ * @type {Object}
+ */
+
+export default QueriesPlugin
diff --git a/packages/slate/src/models/schema.js b/packages/slate/src/plugins/schema.js
similarity index 54%
rename from packages/slate/src/models/schema.js
rename to packages/slate/src/plugins/schema.js
index fb91e1009..c0463c797 100644
--- a/packages/slate/src/models/schema.js
+++ b/packages/slate/src/plugins/schema.js
@@ -1,302 +1,99 @@
-import Debug from 'debug'
-import isPlainObject from 'is-plain-object'
-import { Record } from 'immutable'
-
-import Stack from './stack'
-import Text from './text'
import SlateError from '../utils/slate-error'
+import Queries from './queries'
/**
- * Debug.
+ * Create a plugin from a `schema` definition.
*
- * @type {Function}
+ * @param {Object} schema
+ * @return {Object}
*/
-const debug = Debug('slate:schema')
+function SchemaPlugin(schema) {
+ const { rules, document, blocks, inlines, marks } = schema
+ let schemaRules = []
-/**
- * Define the core schema rules, order-sensitive.
- *
- * @type {Array}
- */
+ if (rules) {
+ schemaRules = schemaRules.concat(rules)
+ }
-const CORE_RULES = [
- // Only allow block nodes in documents.
- {
- match: { object: 'document' },
- nodes: [
- {
- match: { object: 'block' },
- },
- ],
- },
+ if (document) {
+ schemaRules.push({
+ match: [{ object: 'document' }],
+ ...document,
+ })
+ }
- // Only allow block nodes or inline and text nodes in blocks.
- {
- match: {
- object: 'block',
- first: { object: 'block' },
- },
- nodes: [
- {
- match: { object: 'block' },
- },
- ],
- },
- {
- match: {
- object: 'block',
- first: [{ object: 'inline' }, { object: 'text' }],
- },
- nodes: [
- {
- match: [{ object: 'inline' }, { object: 'text' }],
- },
- ],
- },
+ if (blocks) {
+ for (const key in blocks) {
+ schemaRules.push({
+ match: [{ object: 'block', type: key }],
+ ...blocks[key],
+ })
+ }
+ }
- // Only allow inline and text nodes in inlines.
- {
- match: { object: 'inline' },
- nodes: [{ match: [{ object: 'inline' }, { object: 'text' }] }],
- },
+ if (inlines) {
+ for (const key in inlines) {
+ schemaRules.push({
+ match: [{ object: 'inline', type: key }],
+ ...inlines[key],
+ })
+ }
+ }
- // Ensure that block and inline nodes have at least one text child.
- {
- match: [{ object: 'block' }, { object: 'inline' }],
- nodes: [{ min: 1 }],
- normalize: (change, error) => {
- const { code, node } = error
- if (code !== 'child_required') return
- change.insertNodeByKey(node.key, 0, Text.create(), { normalize: false })
- },
- },
+ if (marks) {
+ for (const key in marks) {
+ schemaRules.push({
+ match: [{ object: 'mark', type: key }],
+ ...marks[key],
+ })
+ }
+ }
- // Ensure that inline nodes are surrounded by text nodes.
- {
- match: { object: 'block' },
- first: [{ object: 'block' }, { object: 'text' }],
- last: [{ object: 'block' }, { object: 'text' }],
- normalize: (change, error) => {
- const { code, node } = error
- const text = Text.create()
- let i
-
- if (code === 'first_child_object_invalid') {
- i = 0
- } else if (code === 'last_child_object_invalid') {
- i = node.nodes.size
- } else {
- return
- }
-
- change.insertNodeByKey(node.key, i, text, { normalize: false })
- },
- },
- {
- match: { object: 'inline' },
- first: [{ object: 'block' }, { object: 'text' }],
- last: [{ object: 'block' }, { object: 'text' }],
- previous: [{ object: 'block' }, { object: 'text' }],
- next: [{ object: 'block' }, { object: 'text' }],
- normalize: (change, error) => {
- const { code, node, index } = error
- const text = Text.create()
- let i
-
- if (code === 'first_child_object_invalid') {
- i = 0
- } else if (code === 'last_child_object_invalid') {
- i = node.nodes.size
- } else if (code === 'previous_sibling_object_invalid') {
- i = index
- } else if (code === 'next_sibling_object_invalid') {
- i = index + 1
- } else {
- return
- }
-
- change.insertNodeByKey(node.key, i, text, { normalize: false })
- },
- },
-
- // Merge adjacent text nodes.
- {
- match: { object: 'text' },
- next: [{ object: 'block' }, { object: 'inline' }],
- normalize: (change, error) => {
- const { code, next } = error
- if (code !== 'next_sibling_object_invalid') return
- change.mergeNodeByKey(next.key, { normalize: false })
- },
- },
-]
-
-/**
- * Default properties.
- *
- * @type {Object}
- */
-
-const DEFAULTS = {
- stack: undefined,
- rules: undefined,
-}
-
-/**
- * Schema.
- *
- * @type {Schema}
- */
-
-class Schema extends Record(DEFAULTS) {
/**
- * Create a new `Schema` with `attrs`.
+ * Check if a `mark` is void based on the schema rules.
*
- * @param {Object|Schema} attrs
- * @return {Schema}
+ * @param {Mark} mark
+ * @return {Boolean}
*/
- static create(attrs = {}) {
- if (Schema.isSchema(attrs)) {
- return attrs
- }
-
- if (isPlainObject(attrs)) {
- return Schema.fromJSON(attrs)
- }
-
- throw new Error(
- `\`Schema.create\` only accepts objects or schemas, but you passed it: ${attrs}`
+ function isAtomic(mark) {
+ const rule = schemaRules.find(
+ r => 'isAtomic' in r && testRules(mark, r.match)
)
+
+ return rule && rule.isAtomic
}
/**
- * Create a `Schema` from a JSON `object`.
- *
- * @param {Object} object
- * @return {Schema}
- */
-
- static fromJSON(object) {
- if (Schema.isSchema(object)) {
- return object
- }
-
- const plugins = object.plugins ? object.plugins : [{ schema: object }]
- let rules = [...CORE_RULES]
-
- for (const plugin of plugins) {
- const { schema = {} } = plugin
- const { blocks = {}, inlines = {}, marks = {} } = schema
-
- if (schema.rules) {
- rules = rules.concat(schema.rules)
- }
-
- if (schema.document) {
- rules.push({
- match: [{ object: 'document' }],
- ...schema.document,
- })
- }
-
- for (const key in blocks) {
- rules.push({
- match: [{ object: 'block', type: key }],
- ...blocks[key],
- })
- }
-
- for (const key in inlines) {
- rules.push({
- match: [{ object: 'inline', type: key }],
- ...inlines[key],
- })
- }
-
- for (const key in marks) {
- rules.push({
- match: [{ object: 'mark', type: key }],
- ...marks[key],
- })
- }
- }
-
- const stack = Stack.create({ plugins })
- const ret = new Schema({ stack, rules })
- return ret
- }
-
- /**
- * Get the schema rules for a `node`.
- *
- * @param {Node} node
- * @return {Array}
- */
-
- getNodeRules(node) {
- const rules = this.rules.filter(r => testRules(node, r.match))
- return rules
- }
-
- /**
- * Validate a `node` with the schema, returning an error if it's invalid.
- *
- * @param {Node} node
- * @return {Error|Void}
- */
-
- validateNode(node) {
- const rules = this.getNodeRules(node)
- const failure = validateRules(node, rules, this.rules, { every: true })
- if (!failure) return
- const error = new SlateError(failure.code, failure)
- return error
- }
-
- /**
- * Test whether a `node` is valid against the schema.
+ * Check if a `node` is void based on the schema rules.
*
* @param {Node} node
* @return {Boolean}
*/
- testNode(node) {
- const error = this.validateNode(node)
- return !error
+ function isVoid(node) {
+ const rule = schemaRules.find(
+ r => 'isVoid' in r && testRules(node, r.match)
+ )
+
+ return rule && rule.isVoid
}
/**
- * Assert that a `node` is valid against the schema.
- *
- * @param {Node} node
- * @throws
- */
-
- assertNode(node) {
- const error = this.validateNode(node)
- if (error) throw error
- }
-
- /**
- * Normalize a `node` with the schema, returning a function that will fix the
- * invalid node, or void if the node is valid.
+ * Normalize a `node` with the schema rules, returning a function that will
+ * fix the invalid node, or void if the node is valid.
*
* @param {Node} node
+ * @param {Function} next
* @return {Function|Void}
*/
- normalizeNode(node) {
- const ret = this.stack.find('normalizeNode', node)
- if (ret) return ret
- if (node.object == 'text') return
-
- const error = this.validateNode(node)
- if (!error) return
+ function normalizeNode(node, next) {
+ const error = validateNode(node, () => {})
+ if (!error) return next()
return change => {
- debug(`normalizing`, { error })
const { rule } = error
const { size } = change.operations
@@ -314,46 +111,43 @@ class Schema extends Record(DEFAULTS) {
}
/**
- * Check if a mark is void.
+ * Validate a `node` with the schema rules, returning a `SlateError` if it's
+ * invalid.
*
- * @param {Mark}
- * @return {Boolean}
+ * @param {Node} node
+ * @param {Function} next
+ * @return {Error|Void}
*/
- isAtomic(mark) {
- const rule = this.rules.find(
- r => 'isAtomic' in r && testRules(mark, r.match)
- )
-
- return rule ? rule.isAtomic : false
+ function validateNode(node, next) {
+ const matches = schemaRules.filter(r => testRules(node, r.match))
+ const failure = validateRules(node, matches, schemaRules, { every: true })
+ if (!failure) return next()
+ const error = new SlateError(failure.code, failure)
+ return error
}
/**
- * Check if a node is void.
+ * On schema-related queries, respond if we can.
*
- * @param {Node}
- * @return {Boolean}
+ * @param {Object} query
+ * @param {Function} next
*/
- isVoid(node) {
- const rule = this.rules.find(r => 'isVoid' in r && testRules(node, r.match))
- return rule ? rule.isVoid : false
- }
+ const queries = Queries({
+ queries: {
+ isAtomic,
+ isVoid,
+ },
+ })
/**
- * Return a JSON representation of the schema.
+ * Return the plugins.
*
- * @return {Object}
+ * @type {Object}
*/
- toJSON() {
- const object = {
- object: this.object,
- rules: this.rules,
- }
-
- return object
- }
+ return [{ normalizeNode, validateNode }, queries]
}
/**
@@ -377,8 +171,8 @@ function defaultNormalize(change, error) {
return child.object === 'text' &&
node.object === 'block' &&
node.nodes.size === 1
- ? change.removeNodeByKey(node.key, { normalize: false })
- : change.removeNodeByKey(child.key, { normalize: false })
+ ? change.removeNodeByKey(node.key)
+ : change.removeNodeByKey(child.key)
}
case 'previous_sibling_object_invalid':
@@ -386,8 +180,8 @@ function defaultNormalize(change, error) {
return previous.object === 'text' &&
node.object === 'block' &&
node.nodes.size === 1
- ? change.removeNodeByKey(node.key, { normalize: false })
- : change.removeNodeByKey(previous.key, { normalize: false })
+ ? change.removeNodeByKey(node.key)
+ : change.removeNodeByKey(previous.key)
}
case 'next_sibling_object_invalid':
@@ -395,8 +189,8 @@ function defaultNormalize(change, error) {
return next.object === 'text' &&
node.object === 'block' &&
node.nodes.size === 1
- ? change.removeNodeByKey(node.key, { normalize: false })
- : change.removeNodeByKey(next.key, { normalize: false })
+ ? change.removeNodeByKey(node.key)
+ : change.removeNodeByKey(next.key)
}
case 'child_required':
@@ -404,32 +198,24 @@ function defaultNormalize(change, error) {
case 'parent_object_invalid':
case 'parent_type_invalid': {
return node.object === 'document'
- ? node.nodes.forEach(n =>
- change.removeNodeByKey(n.key, { normalize: false })
- )
- : change.removeNodeByKey(node.key, { normalize: false })
+ ? node.nodes.forEach(n => change.removeNodeByKey(n.key))
+ : change.removeNodeByKey(node.key)
}
case 'node_data_invalid': {
return node.data.get(key) === undefined && node.object !== 'document'
- ? change.removeNodeByKey(node.key, { normalize: false })
- : change.setNodeByKey(
- node.key,
- { data: node.data.delete(key) },
- { normalize: false }
- )
+ ? change.removeNodeByKey(node.key)
+ : change.setNodeByKey(node.key, { data: node.data.delete(key) })
}
case 'node_mark_invalid': {
- return node.getTexts().forEach(t =>
- change.removeMarkByKey(t.key, 0, t.text.length, mark, {
- normalize: false,
- })
- )
+ return node
+ .getTexts()
+ .forEach(t => change.removeMarkByKey(t.key, 0, t.text.length, mark))
}
default: {
- return change.removeNodeByKey(node.key, { normalize: false })
+ return change.removeNodeByKey(node.key)
}
}
}
@@ -725,7 +511,7 @@ function fail(code, attrs) {
/**
* Export.
*
- * @type {Schema}
+ * @type {Object}
*/
-export default Schema
+export default SchemaPlugin
diff --git a/packages/slate/src/utils/is-object.js b/packages/slate/src/utils/is-object.js
index 00bdf0436..2fc0ea7eb 100644
--- a/packages/slate/src/utils/is-object.js
+++ b/packages/slate/src/utils/is-object.js
@@ -9,16 +9,14 @@ export const TYPES = {
change: '@@__SLATE_CHANGE__@@',
decoration: '@@__SLATE_DECORATION__@@',
document: '@@__SLATE_DOCUMENT__@@',
- history: '@@__SLATE_HISTORY__@@',
+ editor: '@@__SLATE_EDITOR__@@',
inline: '@@__SLATE_INLINE__@@',
leaf: '@@__SLATE_LEAF__@@',
mark: '@@__SLATE_MARK__@@',
operation: '@@__SLATE_OPERATION__@@',
point: '@@__SLATE_POINT__@@',
range: '@@__SLATE_RANGE__@@',
- schema: '@@__SLATE_SCHEMA__@@',
selection: '@@__SLATE_SELECTION__@@',
- stack: '@@__SLATE_STACK__@@',
text: '@@__SLATE_TEXT__@@',
value: '@@__SLATE_VALUE__@@',
}
diff --git a/packages/slate/test/changes/at-current-range/add-mark/across-blocks.js b/packages/slate/test/commands/at-current-range/add-mark/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/across-blocks.js
rename to packages/slate/test/commands/at-current-range/add-mark/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/across-inlines.js b/packages/slate/test/commands/at-current-range/add-mark/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/across-inlines.js
rename to packages/slate/test/commands/at-current-range/add-mark/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/collapsed-selection.js b/packages/slate/test/commands/at-current-range/add-mark/collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/add-mark/collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/existing-marks.js b/packages/slate/test/commands/at-current-range/add-mark/existing-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/existing-marks.js
rename to packages/slate/test/commands/at-current-range/add-mark/existing-marks.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/first-character.js b/packages/slate/test/commands/at-current-range/add-mark/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/first-character.js
rename to packages/slate/test/commands/at-current-range/add-mark/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/last-character.js b/packages/slate/test/commands/at-current-range/add-mark/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/last-character.js
rename to packages/slate/test/commands/at-current-range/add-mark/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/middle-character.js b/packages/slate/test/commands/at-current-range/add-mark/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/middle-character.js
rename to packages/slate/test/commands/at-current-range/add-mark/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/whole-word.js b/packages/slate/test/commands/at-current-range/add-mark/whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/whole-word.js
rename to packages/slate/test/commands/at-current-range/add-mark/whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/with-mark-object.js b/packages/slate/test/commands/at-current-range/add-mark/with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/with-mark-object.js
rename to packages/slate/test/commands/at-current-range/add-mark/with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/add-mark/with-plain-object.js b/packages/slate/test/commands/at-current-range/add-mark/with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-mark/with-plain-object.js
rename to packages/slate/test/commands/at-current-range/add-mark/with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/across-blocks.js b/packages/slate/test/commands/at-current-range/add-marks/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/across-blocks.js
rename to packages/slate/test/commands/at-current-range/add-marks/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/across-inlines.js b/packages/slate/test/commands/at-current-range/add-marks/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/across-inlines.js
rename to packages/slate/test/commands/at-current-range/add-marks/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/across-marks.js b/packages/slate/test/commands/at-current-range/add-marks/across-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/across-marks.js
rename to packages/slate/test/commands/at-current-range/add-marks/across-marks.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/collapsed-selection.js b/packages/slate/test/commands/at-current-range/add-marks/collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/add-marks/collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/first-character.js b/packages/slate/test/commands/at-current-range/add-marks/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/first-character.js
rename to packages/slate/test/commands/at-current-range/add-marks/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/inside-mark.js b/packages/slate/test/commands/at-current-range/add-marks/inside-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/inside-mark.js
rename to packages/slate/test/commands/at-current-range/add-marks/inside-mark.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/last-character.js b/packages/slate/test/commands/at-current-range/add-marks/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/last-character.js
rename to packages/slate/test/commands/at-current-range/add-marks/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/middle-character.js b/packages/slate/test/commands/at-current-range/add-marks/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/middle-character.js
rename to packages/slate/test/commands/at-current-range/add-marks/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/whole-word.js b/packages/slate/test/commands/at-current-range/add-marks/whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/whole-word.js
rename to packages/slate/test/commands/at-current-range/add-marks/whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/with-mark-object.js b/packages/slate/test/commands/at-current-range/add-marks/with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/with-mark-object.js
rename to packages/slate/test/commands/at-current-range/add-marks/with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/add-marks/with-plain-object.js b/packages/slate/test/commands/at-current-range/add-marks/with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/add-marks/with-plain-object.js
rename to packages/slate/test/commands/at-current-range/add-marks/with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/empty-after-void-block.js b/packages/slate/test/commands/at-current-range/delete-backward/empty-after-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/empty-after-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-backward/empty-after-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/first-character.js b/packages/slate/test/commands/at-current-range/delete-backward/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/first-character.js
rename to packages/slate/test/commands/at-current-range/delete-backward/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/inline-after.js b/packages/slate/test/commands/at-current-range/delete-backward/inline-after.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/inline-after.js
rename to packages/slate/test/commands/at-current-range/delete-backward/inline-after.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/inline-before.js b/packages/slate/test/commands/at-current-range/delete-backward/inline-before.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/inline-before.js
rename to packages/slate/test/commands/at-current-range/delete-backward/inline-before.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/inline-end.js b/packages/slate/test/commands/at-current-range/delete-backward/inline-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/inline-end.js
rename to packages/slate/test/commands/at-current-range/delete-backward/inline-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js b/packages/slate/test/commands/at-current-range/delete-backward/inline-inside.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js
rename to packages/slate/test/commands/at-current-range/delete-backward/inline-inside.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/join-blocks-with-inline-void.js b/packages/slate/test/commands/at-current-range/delete-backward/join-blocks-with-inline-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/join-blocks-with-inline-void.js
rename to packages/slate/test/commands/at-current-range/delete-backward/join-blocks-with-inline-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/join-blocks-with-inline.js b/packages/slate/test/commands/at-current-range/delete-backward/join-blocks-with-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/join-blocks-with-inline.js
rename to packages/slate/test/commands/at-current-range/delete-backward/join-blocks-with-inline.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/join-blocks.js b/packages/slate/test/commands/at-current-range/delete-backward/join-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/join-blocks.js
rename to packages/slate/test/commands/at-current-range/delete-backward/join-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/join-nested-blocks.js b/packages/slate/test/commands/at-current-range/delete-backward/join-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/join-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/delete-backward/join-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/last-character.js b/packages/slate/test/commands/at-current-range/delete-backward/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/last-character.js
rename to packages/slate/test/commands/at-current-range/delete-backward/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/middle-character.js b/packages/slate/test/commands/at-current-range/delete-backward/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/middle-character.js
rename to packages/slate/test/commands/at-current-range/delete-backward/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/multiple-characters.js b/packages/slate/test/commands/at-current-range/delete-backward/multiple-characters.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/multiple-characters.js
rename to packages/slate/test/commands/at-current-range/delete-backward/multiple-characters.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/single-non-void-block.js b/packages/slate/test/commands/at-current-range/delete-backward/single-non-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/single-non-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-backward/single-non-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/single-void-block.js b/packages/slate/test/commands/at-current-range/delete-backward/single-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/single-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-backward/single-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/start-of-document.js b/packages/slate/test/commands/at-current-range/delete-backward/start-of-document.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-backward/start-of-document.js
rename to packages/slate/test/commands/at-current-range/delete-backward/start-of-document.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-after-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-backward/inline-after-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/inline-after-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/inline-after-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-end-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-backward/inline-end-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/inline-end-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/inline-end-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-inside-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-backward/inline-inside-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/inline-inside-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/inline-inside-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-backward/inline-only-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/inline-only-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/text-end.js b/packages/slate/test/commands/at-current-range/delete-char-backward/text-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/text-end.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/text-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/text-middle.js b/packages/slate/test/commands/at-current-range/delete-char-backward/text-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/text-middle.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/text-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/text-start.js b/packages/slate/test/commands/at-current-range/delete-char-backward/text-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-backward/text-start.js
rename to packages/slate/test/commands/at-current-range/delete-char-backward/text-start.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/inline-before-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-forward/inline-before-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/inline-before-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/inline-before-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/inline-middle-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-forward/inline-middle-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/inline-middle-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/inline-middle-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/inline-start-emoji.js b/packages/slate/test/commands/at-current-range/delete-char-forward/inline-start-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/inline-start-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/inline-start-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/text-last.js b/packages/slate/test/commands/at-current-range/delete-char-forward/text-last.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/text-last.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/text-last.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/text-middle.js b/packages/slate/test/commands/at-current-range/delete-char-forward/text-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/text-middle.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/text-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-char-forward/text-start.js b/packages/slate/test/commands/at-current-range/delete-char-forward/text-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-char-forward/text-start.js
rename to packages/slate/test/commands/at-current-range/delete-char-forward/text-start.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/before-inline-sibling.js b/packages/slate/test/commands/at-current-range/delete-forward/before-inline-sibling.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/before-inline-sibling.js
rename to packages/slate/test/commands/at-current-range/delete-forward/before-inline-sibling.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/empty-before-void-block.js b/packages/slate/test/commands/at-current-range/delete-forward/empty-before-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/empty-before-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-forward/empty-before-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/end-of-document.js b/packages/slate/test/commands/at-current-range/delete-forward/end-of-document.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/end-of-document.js
rename to packages/slate/test/commands/at-current-range/delete-forward/end-of-document.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/first-character.js b/packages/slate/test/commands/at-current-range/delete-forward/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/first-character.js
rename to packages/slate/test/commands/at-current-range/delete-forward/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js b/packages/slate/test/commands/at-current-range/delete-forward/inside-inline-sibling.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js
rename to packages/slate/test/commands/at-current-range/delete-forward/inside-inline-sibling.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/join-blocks-with-inline-void.js b/packages/slate/test/commands/at-current-range/delete-forward/join-blocks-with-inline-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/join-blocks-with-inline-void.js
rename to packages/slate/test/commands/at-current-range/delete-forward/join-blocks-with-inline-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/join-blocks-with-inline.js b/packages/slate/test/commands/at-current-range/delete-forward/join-blocks-with-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/join-blocks-with-inline.js
rename to packages/slate/test/commands/at-current-range/delete-forward/join-blocks-with-inline.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/join-blocks.js b/packages/slate/test/commands/at-current-range/delete-forward/join-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/join-blocks.js
rename to packages/slate/test/commands/at-current-range/delete-forward/join-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/join-nested-blocks.js b/packages/slate/test/commands/at-current-range/delete-forward/join-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/join-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/delete-forward/join-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/last-character.js b/packages/slate/test/commands/at-current-range/delete-forward/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/last-character.js
rename to packages/slate/test/commands/at-current-range/delete-forward/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/middle-character.js b/packages/slate/test/commands/at-current-range/delete-forward/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/middle-character.js
rename to packages/slate/test/commands/at-current-range/delete-forward/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/multiple-characters.js b/packages/slate/test/commands/at-current-range/delete-forward/multiple-characters.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/multiple-characters.js
rename to packages/slate/test/commands/at-current-range/delete-forward/multiple-characters.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/single-non-void-block.js b/packages/slate/test/commands/at-current-range/delete-forward/single-non-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/single-non-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-forward/single-non-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/single-void-block.js b/packages/slate/test/commands/at-current-range/delete-forward/single-void-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/single-void-block.js
rename to packages/slate/test/commands/at-current-range/delete-forward/single-void-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/start-text-middle-inline.js b/packages/slate/test/commands/at-current-range/delete-forward/start-text-middle-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-forward/start-text-middle-inline.js
rename to packages/slate/test/commands/at-current-range/delete-forward/start-text-middle-inline.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/inline-middle-emoji.js b/packages/slate/test/commands/at-current-range/delete-line-backward/inline-middle-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/inline-middle-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/inline-middle-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/inline-multi-voids.js b/packages/slate/test/commands/at-current-range/delete-line-backward/inline-multi-voids.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/inline-multi-voids.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/inline-multi-voids.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/inline-void-first.js b/packages/slate/test/commands/at-current-range/delete-line-backward/inline-void-first.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/inline-void-first.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/inline-void-first.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/text-end.js b/packages/slate/test/commands/at-current-range/delete-line-backward/text-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/text-end.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/text-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/text-start.js b/packages/slate/test/commands/at-current-range/delete-line-backward/text-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/text-start.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/text-start.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-backward/word-middle.js b/packages/slate/test/commands/at-current-range/delete-line-backward/word-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-backward/word-middle.js
rename to packages/slate/test/commands/at-current-range/delete-line-backward/word-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js b/packages/slate/test/commands/at-current-range/delete-line-forward/inline-middle-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/inline-middle-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/inline-multi-voids.js b/packages/slate/test/commands/at-current-range/delete-line-forward/inline-multi-voids.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/inline-multi-voids.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/inline-multi-voids.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/inline-void-end.js b/packages/slate/test/commands/at-current-range/delete-line-forward/inline-void-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/inline-void-end.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/inline-void-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/text-end.js b/packages/slate/test/commands/at-current-range/delete-line-forward/text-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/text-end.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/text-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/text-start.js b/packages/slate/test/commands/at-current-range/delete-line-forward/text-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/text-start.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/text-start.js
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/word-middle.js b/packages/slate/test/commands/at-current-range/delete-line-forward/word-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-line-forward/word-middle.js
rename to packages/slate/test/commands/at-current-range/delete-line-forward/word-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js b/packages/slate/test/commands/at-current-range/delete-word-backward/inline-after-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-word-backward/inline-after-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js b/packages/slate/test/commands/at-current-range/delete-word-backward/inline-middle-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-word-backward/inline-middle-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/join-blocks.js b/packages/slate/test/commands/at-current-range/delete-word-backward/join-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-backward/join-blocks.js
rename to packages/slate/test/commands/at-current-range/delete-word-backward/join-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/text-end.js b/packages/slate/test/commands/at-current-range/delete-word-backward/text-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-backward/text-end.js
rename to packages/slate/test/commands/at-current-range/delete-word-backward/text-end.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/word-middle.js b/packages/slate/test/commands/at-current-range/delete-word-backward/word-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-backward/word-middle.js
rename to packages/slate/test/commands/at-current-range/delete-word-backward/word-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-forward/inline-after-emoji.js b/packages/slate/test/commands/at-current-range/delete-word-forward/inline-after-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-forward/inline-after-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-word-forward/inline-after-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js b/packages/slate/test/commands/at-current-range/delete-word-forward/inline-middle-emoji.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js
rename to packages/slate/test/commands/at-current-range/delete-word-forward/inline-middle-emoji.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-forward/word-middle.js b/packages/slate/test/commands/at-current-range/delete-word-forward/word-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-forward/word-middle.js
rename to packages/slate/test/commands/at-current-range/delete-word-forward/word-middle.js
diff --git a/packages/slate/test/changes/at-current-range/delete-word-forward/word-start.js b/packages/slate/test/commands/at-current-range/delete-word-forward/word-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete-word-forward/word-start.js
rename to packages/slate/test/commands/at-current-range/delete-word-forward/word-start.js
diff --git a/packages/slate/test/changes/at-current-range/delete/across-blocks-inlines.js b/packages/slate/test/commands/at-current-range/delete/across-blocks-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/across-blocks-inlines.js
rename to packages/slate/test/commands/at-current-range/delete/across-blocks-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/delete/across-depths.js b/packages/slate/test/commands/at-current-range/delete/across-depths.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/across-depths.js
rename to packages/slate/test/commands/at-current-range/delete/across-depths.js
diff --git a/packages/slate/test/changes/at-current-range/delete/across-nested-blocks.js b/packages/slate/test/commands/at-current-range/delete/across-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/across-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/delete/across-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete/across-texts-and-inlines.js b/packages/slate/test/commands/at-current-range/delete/across-texts-and-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/across-texts-and-inlines.js
rename to packages/slate/test/commands/at-current-range/delete/across-texts-and-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/delete/before-inline-sibling.js b/packages/slate/test/commands/at-current-range/delete/before-inline-sibling.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/before-inline-sibling.js
rename to packages/slate/test/commands/at-current-range/delete/before-inline-sibling.js
diff --git a/packages/slate/test/changes/at-current-range/delete/first-character.js b/packages/slate/test/commands/at-current-range/delete/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/first-character.js
rename to packages/slate/test/commands/at-current-range/delete/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete/hanging-selection-multiple-blocks.js b/packages/slate/test/commands/at-current-range/delete/hanging-selection-multiple-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/hanging-selection-multiple-blocks.js
rename to packages/slate/test/commands/at-current-range/delete/hanging-selection-multiple-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete/hanging-selection-single-block.js b/packages/slate/test/commands/at-current-range/delete/hanging-selection-single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/hanging-selection-single-block.js
rename to packages/slate/test/commands/at-current-range/delete/hanging-selection-single-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js b/packages/slate/test/commands/at-current-range/delete/inside-inline-sibling.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js
rename to packages/slate/test/commands/at-current-range/delete/inside-inline-sibling.js
diff --git a/packages/slate/test/changes/at-current-range/delete/join-blocks-and-trim.js b/packages/slate/test/commands/at-current-range/delete/join-blocks-and-trim.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/join-blocks-and-trim.js
rename to packages/slate/test/commands/at-current-range/delete/join-blocks-and-trim.js
diff --git a/packages/slate/test/changes/at-current-range/delete/join-blocks-with-inlines.js b/packages/slate/test/commands/at-current-range/delete/join-blocks-with-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/join-blocks-with-inlines.js
rename to packages/slate/test/commands/at-current-range/delete/join-blocks-with-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/delete/join-blocks.js b/packages/slate/test/commands/at-current-range/delete/join-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/join-blocks.js
rename to packages/slate/test/commands/at-current-range/delete/join-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete/join-double-nested-blocks.js b/packages/slate/test/commands/at-current-range/delete/join-double-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/join-double-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/delete/join-double-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete/join-nested-blocks.js b/packages/slate/test/commands/at-current-range/delete/join-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/join-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/delete/join-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/delete/last-character.js b/packages/slate/test/commands/at-current-range/delete/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/last-character.js
rename to packages/slate/test/commands/at-current-range/delete/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete/middle-character.js b/packages/slate/test/commands/at-current-range/delete/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/middle-character.js
rename to packages/slate/test/commands/at-current-range/delete/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/delete/nested-block.js b/packages/slate/test/commands/at-current-range/delete/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/nested-block.js
rename to packages/slate/test/commands/at-current-range/delete/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-only-non-void.js b/packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-only-non-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-only-non-void.js
rename to packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-only-non-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-up-to-start-of-void.js b/packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-up-to-start-of-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-up-to-start-of-void.js
rename to packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-up-to-start-of-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-void.js b/packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-void.js
rename to packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void-and-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void.js b/packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void.js
rename to packages/slate/test/commands/at-current-range/delete/non-void-block-as-first-with-void-siblings-partially-non-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-all.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-all.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-all.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-all.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-backward-selection-all.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-backward-selection-all.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-backward-selection-all.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-backward-selection-all.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-only-void.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-only-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-only-void.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-only-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-and-next-word.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-and-next-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-and-next-word.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-and-next-word.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-end-and-next-word.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-end-and-next-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-end-and-next-word.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-first-with-non-void-siblings-select-void-end-and-next-word.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-block-as-only.js b/packages/slate/test/commands/at-current-range/delete/void-block-as-only.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-block-as-only.js
rename to packages/slate/test/commands/at-current-range/delete/void-block-as-only.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-first-void.js b/packages/slate/test/commands/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-first-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-first-void.js
rename to packages/slate/test/commands/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-first-void.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-voids.js b/packages/slate/test/commands/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-voids.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-voids.js
rename to packages/slate/test/commands/at-current-range/delete/void-blocks-as-first-with-non-void-siblings-only-voids.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-inline-as-first-with-non-void-block-next.js b/packages/slate/test/commands/at-current-range/delete/void-inline-as-first-with-non-void-block-next.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-inline-as-first-with-non-void-block-next.js
rename to packages/slate/test/commands/at-current-range/delete/void-inline-as-first-with-non-void-block-next.js
diff --git a/packages/slate/test/changes/at-current-range/delete/void-inline-as-first-with-non-void-sibling.js b/packages/slate/test/commands/at-current-range/delete/void-inline-as-first-with-non-void-sibling.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/void-inline-as-first-with-non-void-sibling.js
rename to packages/slate/test/commands/at-current-range/delete/void-inline-as-first-with-non-void-sibling.js
diff --git a/packages/slate/test/changes/at-current-range/delete/whole-inline.js b/packages/slate/test/commands/at-current-range/delete/whole-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/whole-inline.js
rename to packages/slate/test/commands/at-current-range/delete/whole-inline.js
diff --git a/packages/slate/test/changes/at-current-range/delete/whole-word.js b/packages/slate/test/commands/at-current-range/delete/whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/delete/whole-word.js
rename to packages/slate/test/commands/at-current-range/delete/whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/block-end.js b/packages/slate/test/commands/at-current-range/insert-block/block-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/block-end.js
rename to packages/slate/test/commands/at-current-range/insert-block/block-end.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/block-middle.js b/packages/slate/test/commands/at-current-range/insert-block/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/block-middle.js
rename to packages/slate/test/commands/at-current-range/insert-block/block-middle.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/block-start.js b/packages/slate/test/commands/at-current-range/insert-block/block-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/block-start.js
rename to packages/slate/test/commands/at-current-range/insert-block/block-start.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/is-empty.js b/packages/slate/test/commands/at-current-range/insert-block/is-empty.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/is-empty.js
rename to packages/slate/test/commands/at-current-range/insert-block/is-empty.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/is-inline-void.js b/packages/slate/test/commands/at-current-range/insert-block/is-inline-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/is-inline-void.js
rename to packages/slate/test/commands/at-current-range/insert-block/is-inline-void.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/is-void-end.js b/packages/slate/test/commands/at-current-range/insert-block/is-void-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/is-void-end.js
rename to packages/slate/test/commands/at-current-range/insert-block/is-void-end.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/is-void-start.js b/packages/slate/test/commands/at-current-range/insert-block/is-void-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/is-void-start.js
rename to packages/slate/test/commands/at-current-range/insert-block/is-void-start.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/with-block.js b/packages/slate/test/commands/at-current-range/insert-block/with-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/with-block.js
rename to packages/slate/test/commands/at-current-range/insert-block/with-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-block/with-object.js b/packages/slate/test/commands/at-current-range/insert-block/with-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-block/with-object.js
rename to packages/slate/test/commands/at-current-range/insert-block/with-object.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/end-block-multiple-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/end-block-multiple-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/end-block-multiple-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/end-block-multiple-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/end-block.js b/packages/slate/test/commands/at-current-range/insert-fragment/end-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/end-block.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/end-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js b/packages/slate/test/commands/at-current-range/insert-fragment/end-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/end-inline.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/fragment-multiple-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-multiple-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/fragment-multiple-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/fragment-multiple-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/fragment-nested-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/fragment-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/fragment-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/hanging-selection-single-block.js b/packages/slate/test/commands/at-current-range/insert-fragment/hanging-selection-single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/hanging-selection-single-block.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/hanging-selection-single-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/middle-block.js b/packages/slate/test/commands/at-current-range/insert-fragment/middle-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/middle-block.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/middle-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/middle-inline-fragment-inline.js b/packages/slate/test/commands/at-current-range/insert-fragment/middle-inline-fragment-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/middle-inline-fragment-inline.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/middle-inline-fragment-inline.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/middle-inline.js b/packages/slate/test/commands/at-current-range/insert-fragment/middle-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/middle-inline.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/middle-inline.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/nested-block-fragment-nested-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/nested-block-fragment-nested-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/nested-block-fragment-nested-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/nested-block-fragment-nested-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/start-block-multiple-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/start-block-multiple-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/start-block-multiple-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/start-block-multiple-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/start-block.js b/packages/slate/test/commands/at-current-range/insert-fragment/start-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/start-block.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/start-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/start-inline.js b/packages/slate/test/commands/at-current-range/insert-fragment/start-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/start-inline.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/start-inline.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/start-second-block.js b/packages/slate/test/commands/at-current-range/insert-fragment/start-second-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/start-second-block.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/start-second-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/with-delete-across-blocks.js b/packages/slate/test/commands/at-current-range/insert-fragment/with-delete-across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-fragment/with-delete-across-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-fragment/with-delete-across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-end.js b/packages/slate/test/commands/at-current-range/insert-inline/block-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/block-end.js
rename to packages/slate/test/commands/at-current-range/insert-inline/block-end.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-middle.js b/packages/slate/test/commands/at-current-range/insert-inline/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/block-middle.js
rename to packages/slate/test/commands/at-current-range/insert-inline/block-middle.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-start.js b/packages/slate/test/commands/at-current-range/insert-inline/block-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/block-start.js
rename to packages/slate/test/commands/at-current-range/insert-inline/block-start.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js b/packages/slate/test/commands/at-current-range/insert-inline/inline-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js
rename to packages/slate/test/commands/at-current-range/insert-inline/inline-middle.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/is-empty.js b/packages/slate/test/commands/at-current-range/insert-inline/is-empty.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/is-empty.js
rename to packages/slate/test/commands/at-current-range/insert-inline/is-empty.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/is-void.js b/packages/slate/test/commands/at-current-range/insert-inline/is-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/is-void.js
rename to packages/slate/test/commands/at-current-range/insert-inline/is-void.js
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/with-inline.js b/packages/slate/test/commands/at-current-range/insert-inline/with-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-inline/with-inline.js
rename to packages/slate/test/commands/at-current-range/insert-inline/with-inline.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/after-mark.js b/packages/slate/test/commands/at-current-range/insert-text/after-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/after-mark.js
rename to packages/slate/test/commands/at-current-range/insert-text/after-mark.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/before-mark.js b/packages/slate/test/commands/at-current-range/insert-text/before-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/before-mark.js
rename to packages/slate/test/commands/at-current-range/insert-text/before-mark.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/blocks-with-overlapping-marks.js b/packages/slate/test/commands/at-current-range/insert-text/blocks-with-overlapping-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/blocks-with-overlapping-marks.js
rename to packages/slate/test/commands/at-current-range/insert-text/blocks-with-overlapping-marks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/during-mark.js b/packages/slate/test/commands/at-current-range/insert-text/during-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/during-mark.js
rename to packages/slate/test/commands/at-current-range/insert-text/during-mark.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/empty-block-with-mark.js b/packages/slate/test/commands/at-current-range/insert-text/empty-block-with-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/empty-block-with-mark.js
rename to packages/slate/test/commands/at-current-range/insert-text/empty-block-with-mark.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/expanded-with-mark.js b/packages/slate/test/commands/at-current-range/insert-text/expanded-with-mark.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/expanded-with-mark.js
rename to packages/slate/test/commands/at-current-range/insert-text/expanded-with-mark.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/first-character.js b/packages/slate/test/commands/at-current-range/insert-text/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/first-character.js
rename to packages/slate/test/commands/at-current-range/insert-text/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/first-space.js b/packages/slate/test/commands/at-current-range/insert-text/first-space.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/first-space.js
rename to packages/slate/test/commands/at-current-range/insert-text/first-space.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/first-words.js b/packages/slate/test/commands/at-current-range/insert-text/first-words.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/first-words.js
rename to packages/slate/test/commands/at-current-range/insert-text/first-words.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/hanging-selection-multiple-blocks.js b/packages/slate/test/commands/at-current-range/insert-text/hanging-selection-multiple-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/hanging-selection-multiple-blocks.js
rename to packages/slate/test/commands/at-current-range/insert-text/hanging-selection-multiple-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/hanging-selection-single-block.js b/packages/slate/test/commands/at-current-range/insert-text/hanging-selection-single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/hanging-selection-single-block.js
rename to packages/slate/test/commands/at-current-range/insert-text/hanging-selection-single-block.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/inside-void.js b/packages/slate/test/commands/at-current-range/insert-text/inside-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/inside-void.js
rename to packages/slate/test/commands/at-current-range/insert-text/inside-void.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/last-character.js b/packages/slate/test/commands/at-current-range/insert-text/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/last-character.js
rename to packages/slate/test/commands/at-current-range/insert-text/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/last-space.js b/packages/slate/test/commands/at-current-range/insert-text/last-space.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/last-space.js
rename to packages/slate/test/commands/at-current-range/insert-text/last-space.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/last-words.js b/packages/slate/test/commands/at-current-range/insert-text/last-words.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/last-words.js
rename to packages/slate/test/commands/at-current-range/insert-text/last-words.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/middle-character.js b/packages/slate/test/commands/at-current-range/insert-text/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/middle-character.js
rename to packages/slate/test/commands/at-current-range/insert-text/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/middle-space.js b/packages/slate/test/commands/at-current-range/insert-text/middle-space.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/middle-space.js
rename to packages/slate/test/commands/at-current-range/insert-text/middle-space.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/middle-words.js b/packages/slate/test/commands/at-current-range/insert-text/middle-words.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/middle-words.js
rename to packages/slate/test/commands/at-current-range/insert-text/middle-words.js
diff --git a/packages/slate/test/changes/at-current-range/insert-text/with-marks.js b/packages/slate/test/commands/at-current-range/insert-text/with-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/insert-text/with-marks.js
rename to packages/slate/test/commands/at-current-range/insert-text/with-marks.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/across-blocks.js b/packages/slate/test/commands/at-current-range/remove-mark/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/across-blocks.js
rename to packages/slate/test/commands/at-current-range/remove-mark/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/across-inlines.js b/packages/slate/test/commands/at-current-range/remove-mark/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/across-inlines.js
rename to packages/slate/test/commands/at-current-range/remove-mark/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/collapsed-selection.js b/packages/slate/test/commands/at-current-range/remove-mark/collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/remove-mark/collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/existing-marks.js b/packages/slate/test/commands/at-current-range/remove-mark/existing-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/existing-marks.js
rename to packages/slate/test/commands/at-current-range/remove-mark/existing-marks.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/first-character.js b/packages/slate/test/commands/at-current-range/remove-mark/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/first-character.js
rename to packages/slate/test/commands/at-current-range/remove-mark/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/last-character.js b/packages/slate/test/commands/at-current-range/remove-mark/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/last-character.js
rename to packages/slate/test/commands/at-current-range/remove-mark/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/middle-character.js b/packages/slate/test/commands/at-current-range/remove-mark/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/middle-character.js
rename to packages/slate/test/commands/at-current-range/remove-mark/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/whole-word.js b/packages/slate/test/commands/at-current-range/remove-mark/whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/whole-word.js
rename to packages/slate/test/commands/at-current-range/remove-mark/whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/with-mark-object.js b/packages/slate/test/commands/at-current-range/remove-mark/with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/with-mark-object.js
rename to packages/slate/test/commands/at-current-range/remove-mark/with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/remove-mark/with-plain-object.js b/packages/slate/test/commands/at-current-range/remove-mark/with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/remove-mark/with-plain-object.js
rename to packages/slate/test/commands/at-current-range/remove-mark/with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/across-blocks.js b/packages/slate/test/commands/at-current-range/replace-mark/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/across-blocks.js
rename to packages/slate/test/commands/at-current-range/replace-mark/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/across-inlines.js b/packages/slate/test/commands/at-current-range/replace-mark/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/across-inlines.js
rename to packages/slate/test/commands/at-current-range/replace-mark/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/collapsed-selection.js b/packages/slate/test/commands/at-current-range/replace-mark/collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/replace-mark/collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/existing-marks.js b/packages/slate/test/commands/at-current-range/replace-mark/existing-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/existing-marks.js
rename to packages/slate/test/commands/at-current-range/replace-mark/existing-marks.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/first-character.js b/packages/slate/test/commands/at-current-range/replace-mark/first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/first-character.js
rename to packages/slate/test/commands/at-current-range/replace-mark/first-character.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/last-character.js b/packages/slate/test/commands/at-current-range/replace-mark/last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/last-character.js
rename to packages/slate/test/commands/at-current-range/replace-mark/last-character.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/middle-character.js b/packages/slate/test/commands/at-current-range/replace-mark/middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/middle-character.js
rename to packages/slate/test/commands/at-current-range/replace-mark/middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/whole-word.js b/packages/slate/test/commands/at-current-range/replace-mark/whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/whole-word.js
rename to packages/slate/test/commands/at-current-range/replace-mark/whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/with-mark-object.js b/packages/slate/test/commands/at-current-range/replace-mark/with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/with-mark-object.js
rename to packages/slate/test/commands/at-current-range/replace-mark/with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/replace-mark/with-plain-object.js b/packages/slate/test/commands/at-current-range/replace-mark/with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/replace-mark/with-plain-object.js
rename to packages/slate/test/commands/at-current-range/replace-mark/with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/across-blocks.js b/packages/slate/test/commands/at-current-range/set-block/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/across-blocks.js
rename to packages/slate/test/commands/at-current-range/set-block/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/across-inlines.js b/packages/slate/test/commands/at-current-range/set-block/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/across-inlines.js
rename to packages/slate/test/commands/at-current-range/set-block/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/data-only.js b/packages/slate/test/commands/at-current-range/set-block/data-only.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/data-only.js
rename to packages/slate/test/commands/at-current-range/set-block/data-only.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/hanging-selection.js b/packages/slate/test/commands/at-current-range/set-block/hanging-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/hanging-selection.js
rename to packages/slate/test/commands/at-current-range/set-block/hanging-selection.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/nested-block.js b/packages/slate/test/commands/at-current-range/set-block/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/nested-block.js
rename to packages/slate/test/commands/at-current-range/set-block/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/single-block-string-shorthand.js b/packages/slate/test/commands/at-current-range/set-block/single-block-string-shorthand.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/single-block-string-shorthand.js
rename to packages/slate/test/commands/at-current-range/set-block/single-block-string-shorthand.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/single-block.js b/packages/slate/test/commands/at-current-range/set-block/single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/single-block.js
rename to packages/slate/test/commands/at-current-range/set-block/single-block.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/with-data-as-map.js b/packages/slate/test/commands/at-current-range/set-block/with-data-as-map.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/with-data-as-map.js
rename to packages/slate/test/commands/at-current-range/set-block/with-data-as-map.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/with-data-as-object.js b/packages/slate/test/commands/at-current-range/set-block/with-data-as-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/with-data-as-object.js
rename to packages/slate/test/commands/at-current-range/set-block/with-data-as-object.js
diff --git a/packages/slate/test/changes/at-current-range/set-block/with-is-void.js b/packages/slate/test/commands/at-current-range/set-block/with-is-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-block/with-is-void.js
rename to packages/slate/test/commands/at-current-range/set-block/with-is-void.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/across-inlines.js b/packages/slate/test/commands/at-current-range/set-inline/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/across-inlines.js
rename to packages/slate/test/commands/at-current-range/set-inline/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/data-only.js b/packages/slate/test/commands/at-current-range/set-inline/data-only.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/data-only.js
rename to packages/slate/test/commands/at-current-range/set-inline/data-only.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/nested-inline.js b/packages/slate/test/commands/at-current-range/set-inline/nested-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/nested-inline.js
rename to packages/slate/test/commands/at-current-range/set-inline/nested-inline.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/single-inline-string-shorthand.js b/packages/slate/test/commands/at-current-range/set-inline/single-inline-string-shorthand.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/single-inline-string-shorthand.js
rename to packages/slate/test/commands/at-current-range/set-inline/single-inline-string-shorthand.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/single-inline.js b/packages/slate/test/commands/at-current-range/set-inline/single-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/single-inline.js
rename to packages/slate/test/commands/at-current-range/set-inline/single-inline.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/with-data-object.js b/packages/slate/test/commands/at-current-range/set-inline/with-data-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/with-data-object.js
rename to packages/slate/test/commands/at-current-range/set-inline/with-data-object.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/with-data.js b/packages/slate/test/commands/at-current-range/set-inline/with-data.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/with-data.js
rename to packages/slate/test/commands/at-current-range/set-inline/with-data.js
diff --git a/packages/slate/test/changes/at-current-range/set-inline/with-is-void.js b/packages/slate/test/commands/at-current-range/set-inline/with-is-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/set-inline/with-is-void.js
rename to packages/slate/test/commands/at-current-range/set-inline/with-is-void.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/after-inline-void.js b/packages/slate/test/commands/at-current-range/split-block/after-inline-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/after-inline-void.js
rename to packages/slate/test/commands/at-current-range/split-block/after-inline-void.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/after-inline.js b/packages/slate/test/commands/at-current-range/split-block/after-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/after-inline.js
rename to packages/slate/test/commands/at-current-range/split-block/after-inline.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/before-inline.js b/packages/slate/test/commands/at-current-range/split-block/before-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/before-inline.js
rename to packages/slate/test/commands/at-current-range/split-block/before-inline.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/block-end.js b/packages/slate/test/commands/at-current-range/split-block/block-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/block-end.js
rename to packages/slate/test/commands/at-current-range/split-block/block-end.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/block-middle.js b/packages/slate/test/commands/at-current-range/split-block/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/block-middle.js
rename to packages/slate/test/commands/at-current-range/split-block/block-middle.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/block-start.js b/packages/slate/test/commands/at-current-range/split-block/block-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/block-start.js
rename to packages/slate/test/commands/at-current-range/split-block/block-start.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/depth.js b/packages/slate/test/commands/at-current-range/split-block/depth.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/depth.js
rename to packages/slate/test/commands/at-current-range/split-block/depth.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js b/packages/slate/test/commands/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
rename to packages/slate/test/commands/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks.js b/packages/slate/test/commands/at-current-range/split-block/with-delete-across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks.js
rename to packages/slate/test/commands/at-current-range/split-block/with-delete-across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-delete-hanging-selection.js b/packages/slate/test/commands/at-current-range/split-block/with-delete-hanging-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-delete-hanging-selection.js
rename to packages/slate/test/commands/at-current-range/split-block/with-delete-hanging-selection.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-delete.js b/packages/slate/test/commands/at-current-range/split-block/with-delete.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-delete.js
rename to packages/slate/test/commands/at-current-range/split-block/with-delete.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-inline.js b/packages/slate/test/commands/at-current-range/split-block/with-inline.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-inline.js
rename to packages/slate/test/commands/at-current-range/split-block/with-inline.js
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-marks.js b/packages/slate/test/commands/at-current-range/split-block/with-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-block/with-marks.js
rename to packages/slate/test/commands/at-current-range/split-block/with-marks.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/block-end.js b/packages/slate/test/commands/at-current-range/split-inline/block-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/block-end.js
rename to packages/slate/test/commands/at-current-range/split-inline/block-end.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/block-middle.js b/packages/slate/test/commands/at-current-range/split-inline/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/block-middle.js
rename to packages/slate/test/commands/at-current-range/split-inline/block-middle.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/block-start.js b/packages/slate/test/commands/at-current-range/split-inline/block-start.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/block-start.js
rename to packages/slate/test/commands/at-current-range/split-inline/block-start.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/depth.js b/packages/slate/test/commands/at-current-range/split-inline/depth.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/depth.js
rename to packages/slate/test/commands/at-current-range/split-inline/depth.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/with-delete.js b/packages/slate/test/commands/at-current-range/split-inline/with-delete.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/with-delete.js
rename to packages/slate/test/commands/at-current-range/split-inline/with-delete.js
diff --git a/packages/slate/test/changes/at-current-range/split-inline/with-marks.js b/packages/slate/test/commands/at-current-range/split-inline/with-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/split-inline/with-marks.js
rename to packages/slate/test/commands/at-current-range/split-inline/with-marks.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-across-blocks.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-across-blocks.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-across-inlines.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-across-inlines.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-collapsed-selection-beginning.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-collapsed-selection-beginning.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-collapsed-selection-beginning.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-collapsed-selection-beginning.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-collapsed-selection.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-existing-marks-partially-marked.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-existing-marks-partially-marked.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-existing-marks-partially-marked.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-existing-marks-partially-marked.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-existing-marks.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-existing-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-existing-marks.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-existing-marks.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-first-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-first-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-first-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-last-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-last-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-last-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-middle-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-middle-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-partially-marked.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-partially-marked.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-partially-marked.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-partially-marked.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-whole-word.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-whole-word.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-with-mark-object.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-with-mark-object.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/add-with-plain-object.js b/packages/slate/test/commands/at-current-range/toggle-mark/add-with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/add-with-plain-object.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/add-with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-across-blocks.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-across-blocks.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-across-inlines.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-across-inlines.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-collapsed-selection-beginning.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-collapsed-selection-beginning.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-collapsed-selection-beginning.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-collapsed-selection-beginning.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-collapsed-selection.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-collapsed-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-collapsed-selection.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-collapsed-selection.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-existing-marks.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-existing-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-existing-marks.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-existing-marks.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-first-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-first-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-first-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-first-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-last-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-last-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-last-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-last-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-middle-character.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-middle-character.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-middle-character.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-middle-character.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-whole-word.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-whole-word.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-whole-word.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-whole-word.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-with-mark-object.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-with-mark-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-with-mark-object.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-with-mark-object.js
diff --git a/packages/slate/test/changes/at-current-range/toggle-mark/remove-with-plain-object.js b/packages/slate/test/commands/at-current-range/toggle-mark/remove-with-plain-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/toggle-mark/remove-with-plain-object.js
rename to packages/slate/test/commands/at-current-range/toggle-mark/remove-with-plain-object.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/across-blocks.js b/packages/slate/test/commands/at-current-range/unwrap-block/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/across-blocks.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/across-inlines.js b/packages/slate/test/commands/at-current-range/unwrap-block/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/across-inlines.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/ending-child-blocks.js b/packages/slate/test/commands/at-current-range/unwrap-block/ending-child-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/ending-child-blocks.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/ending-child-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/middle-child-blocks-with-backward-selection.js b/packages/slate/test/commands/at-current-range/unwrap-block/middle-child-blocks-with-backward-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/middle-child-blocks-with-backward-selection.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/middle-child-blocks-with-backward-selection.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/middle-child-blocks.js b/packages/slate/test/commands/at-current-range/unwrap-block/middle-child-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/middle-child-blocks.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/middle-child-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/nested-block.js b/packages/slate/test/commands/at-current-range/unwrap-block/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/nested-block.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/single-block.js b/packages/slate/test/commands/at-current-range/unwrap-block/single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/single-block.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/single-block.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/starting-child-blocks.js b/packages/slate/test/commands/at-current-range/unwrap-block/starting-child-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/starting-child-blocks.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/starting-child-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-block/with-object.js b/packages/slate/test/commands/at-current-range/unwrap-block/with-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-block/with-object.js
rename to packages/slate/test/commands/at-current-range/unwrap-block/with-object.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/across-blocks.js b/packages/slate/test/commands/at-current-range/unwrap-inline/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/across-blocks.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/across-inlines-and-text.js b/packages/slate/test/commands/at-current-range/unwrap-inline/across-inlines-and-text.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/across-inlines-and-text.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/across-inlines-and-text.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/across-inlines.js b/packages/slate/test/commands/at-current-range/unwrap-inline/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/across-inlines.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/nested-block.js b/packages/slate/test/commands/at-current-range/unwrap-inline/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/nested-block.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/only-one.js b/packages/slate/test/commands/at-current-range/unwrap-inline/only-one.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/only-one.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/only-one.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/single-block.js b/packages/slate/test/commands/at-current-range/unwrap-inline/single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/single-block.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/single-block.js
diff --git a/packages/slate/test/changes/at-current-range/unwrap-inline/with-object.js b/packages/slate/test/commands/at-current-range/unwrap-inline/with-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/unwrap-inline/with-object.js
rename to packages/slate/test/commands/at-current-range/unwrap-inline/with-object.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-block/across-blocks.js b/packages/slate/test/commands/at-current-range/wrap-block/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-block/across-blocks.js
rename to packages/slate/test/commands/at-current-range/wrap-block/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-block/across-inlines.js b/packages/slate/test/commands/at-current-range/wrap-block/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-block/across-inlines.js
rename to packages/slate/test/commands/at-current-range/wrap-block/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-block/nested-block.js b/packages/slate/test/commands/at-current-range/wrap-block/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-block/nested-block.js
rename to packages/slate/test/commands/at-current-range/wrap-block/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-block/single-block.js b/packages/slate/test/commands/at-current-range/wrap-block/single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-block/single-block.js
rename to packages/slate/test/commands/at-current-range/wrap-block/single-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-block/with-object.js b/packages/slate/test/commands/at-current-range/wrap-block/with-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-block/with-object.js
rename to packages/slate/test/commands/at-current-range/wrap-block/with-object.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/across-blocks.js b/packages/slate/test/commands/at-current-range/wrap-inline/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/across-blocks.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/across-inlines.js b/packages/slate/test/commands/at-current-range/wrap-inline/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/across-inlines.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/inline-void.js b/packages/slate/test/commands/at-current-range/wrap-inline/inline-void.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/inline-void.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/inline-void.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-begining.js b/packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-begining.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-begining.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-begining.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-end.js b/packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-end.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-end.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-end.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-with-marks.js b/packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-with-marks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines-with-marks.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines-with-marks.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines.js b/packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/inside-inlines.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/inside-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/nested-block.js b/packages/slate/test/commands/at-current-range/wrap-inline/nested-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/nested-block.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/nested-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/single-block.js b/packages/slate/test/commands/at-current-range/wrap-inline/single-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/single-block.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/single-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/twice.js b/packages/slate/test/commands/at-current-range/wrap-inline/twice.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/twice.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/twice.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/whole-block.js b/packages/slate/test/commands/at-current-range/wrap-inline/whole-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/whole-block.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/whole-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/with-object.js b/packages/slate/test/commands/at-current-range/wrap-inline/with-object.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-inline/with-object.js
rename to packages/slate/test/commands/at-current-range/wrap-inline/with-object.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/across-blocks.js b/packages/slate/test/commands/at-current-range/wrap-text/across-blocks.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/across-blocks.js
rename to packages/slate/test/commands/at-current-range/wrap-text/across-blocks.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/across-inlines.js b/packages/slate/test/commands/at-current-range/wrap-text/across-inlines.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/across-inlines.js
rename to packages/slate/test/commands/at-current-range/wrap-text/across-inlines.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/backwards-selection.js b/packages/slate/test/commands/at-current-range/wrap-text/backwards-selection.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/backwards-selection.js
rename to packages/slate/test/commands/at-current-range/wrap-text/backwards-selection.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/empty-block.js b/packages/slate/test/commands/at-current-range/wrap-text/empty-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/empty-block.js
rename to packages/slate/test/commands/at-current-range/wrap-text/empty-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/end-of-block.js b/packages/slate/test/commands/at-current-range/wrap-text/end-of-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/end-of-block.js
rename to packages/slate/test/commands/at-current-range/wrap-text/end-of-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/middle-of-block.js b/packages/slate/test/commands/at-current-range/wrap-text/middle-of-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/middle-of-block.js
rename to packages/slate/test/commands/at-current-range/wrap-text/middle-of-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/start-of-block.js b/packages/slate/test/commands/at-current-range/wrap-text/start-of-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/start-of-block.js
rename to packages/slate/test/commands/at-current-range/wrap-text/start-of-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/whole-block.js b/packages/slate/test/commands/at-current-range/wrap-text/whole-block.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/whole-block.js
rename to packages/slate/test/commands/at-current-range/wrap-text/whole-block.js
diff --git a/packages/slate/test/changes/at-current-range/wrap-text/without-suffix.js b/packages/slate/test/commands/at-current-range/wrap-text/without-suffix.js
similarity index 100%
rename from packages/slate/test/changes/at-current-range/wrap-text/without-suffix.js
rename to packages/slate/test/commands/at-current-range/wrap-text/without-suffix.js
diff --git a/packages/slate/test/changes/by-key/insert-fragment-by-key/end-of-target.js b/packages/slate/test/commands/by-key/insert-fragment-by-key/end-of-target.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-fragment-by-key/end-of-target.js
rename to packages/slate/test/commands/by-key/insert-fragment-by-key/end-of-target.js
diff --git a/packages/slate/test/changes/by-key/insert-fragment-by-key/middle-of-target.js b/packages/slate/test/commands/by-key/insert-fragment-by-key/middle-of-target.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-fragment-by-key/middle-of-target.js
rename to packages/slate/test/commands/by-key/insert-fragment-by-key/middle-of-target.js
diff --git a/packages/slate/test/changes/by-key/insert-fragment-by-key/start-of-target.js b/packages/slate/test/commands/by-key/insert-fragment-by-key/start-of-target.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-fragment-by-key/start-of-target.js
rename to packages/slate/test/commands/by-key/insert-fragment-by-key/start-of-target.js
diff --git a/packages/slate/test/changes/by-key/insert-node-by-key/block.js b/packages/slate/test/commands/by-key/insert-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-node-by-key/block.js
rename to packages/slate/test/commands/by-key/insert-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/insert-node-by-key/duplicate.js b/packages/slate/test/commands/by-key/insert-node-by-key/duplicate.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-node-by-key/duplicate.js
rename to packages/slate/test/commands/by-key/insert-node-by-key/duplicate.js
diff --git a/packages/slate/test/changes/by-key/insert-node-by-key/inline.js b/packages/slate/test/commands/by-key/insert-node-by-key/inline.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-node-by-key/inline.js
rename to packages/slate/test/commands/by-key/insert-node-by-key/inline.js
diff --git a/packages/slate/test/commands/by-key/insert-text-by-key/decoration-after-atomic.js b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-after-atomic.js
new file mode 100644
index 000000000..3c51a7e75
--- /dev/null
+++ b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-after-atomic.js
@@ -0,0 +1,33 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(change) {
+ change.insertTextByKey('a', 4, 'x')
+}
+
+export const options = {
+ preserveDecorations: true,
+}
+
+export const input = (
+
+
+
+
+ wor d
+
+
+
+
+)
+
+export const output = (
+
+
+
+ wor dx
+
+
+
+)
diff --git a/packages/slate/test/commands/by-key/insert-text-by-key/decoration-before-atomic.js b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-before-atomic.js
new file mode 100644
index 000000000..5532a1e75
--- /dev/null
+++ b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-before-atomic.js
@@ -0,0 +1,33 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(change) {
+ change.insertTextByKey('a', 1, 'x')
+}
+
+export const options = {
+ preserveDecorations: true,
+}
+
+export const input = (
+
+
+
+
+ wor d
+
+
+
+
+)
+
+export const output = (
+
+
+
+ wxor d
+
+
+
+)
diff --git a/packages/slate/test/commands/by-key/insert-text-by-key/decoration-middle-atomic.js b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-middle-atomic.js
new file mode 100644
index 000000000..e9bbc0ce5
--- /dev/null
+++ b/packages/slate/test/commands/by-key/insert-text-by-key/decoration-middle-atomic.js
@@ -0,0 +1,31 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(change) {
+ change.insertTextByKey('a', 2, 'x')
+}
+
+export const options = {
+ preserveDecorations: true,
+}
+
+export const input = (
+
+
+
+
+ wor d
+
+
+
+
+)
+
+export const output = (
+
+
+ woxrd
+
+
+)
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/selection-after.js b/packages/slate/test/commands/by-key/insert-text-by-key/selection-after.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/selection-after.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/selection-after.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/selection-before.js b/packages/slate/test/commands/by-key/insert-text-by-key/selection-before.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/selection-before.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/selection-before.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/selection-end.js b/packages/slate/test/commands/by-key/insert-text-by-key/selection-end.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/selection-end.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/selection-end.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/selection-middle.js b/packages/slate/test/commands/by-key/insert-text-by-key/selection-middle.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/selection-middle.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/selection-middle.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/selection-start.js b/packages/slate/test/commands/by-key/insert-text-by-key/selection-start.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/selection-start.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/selection-start.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/start-text.js b/packages/slate/test/commands/by-key/insert-text-by-key/start-text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/start-text.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/start-text.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/text-end.js b/packages/slate/test/commands/by-key/insert-text-by-key/text-end.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/text-end.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/text-end.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/text-middle-with-marks.js b/packages/slate/test/commands/by-key/insert-text-by-key/text-middle-with-marks.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/text-middle-with-marks.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/text-middle-with-marks.js
diff --git a/packages/slate/test/changes/by-key/insert-text-by-key/text-middle.js b/packages/slate/test/commands/by-key/insert-text-by-key/text-middle.js
similarity index 100%
rename from packages/slate/test/changes/by-key/insert-text-by-key/text-middle.js
rename to packages/slate/test/commands/by-key/insert-text-by-key/text-middle.js
diff --git a/packages/slate/test/changes/by-key/merge-node-by-key/block.js b/packages/slate/test/commands/by-key/merge-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/merge-node-by-key/block.js
rename to packages/slate/test/commands/by-key/merge-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/move-node-by-key/block.js b/packages/slate/test/commands/by-key/move-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/move-node-by-key/block.js
rename to packages/slate/test/commands/by-key/move-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/move-node-by-key/inline.js b/packages/slate/test/commands/by-key/move-node-by-key/inline.js
similarity index 100%
rename from packages/slate/test/changes/by-key/move-node-by-key/inline.js
rename to packages/slate/test/commands/by-key/move-node-by-key/inline.js
diff --git a/packages/slate/test/changes/by-key/move-node-by-key/text.js b/packages/slate/test/commands/by-key/move-node-by-key/text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/move-node-by-key/text.js
rename to packages/slate/test/commands/by-key/move-node-by-key/text.js
diff --git a/packages/slate/test/changes/by-key/move-node-by-key/to-sibling.js b/packages/slate/test/commands/by-key/move-node-by-key/to-sibling.js
similarity index 100%
rename from packages/slate/test/changes/by-key/move-node-by-key/to-sibling.js
rename to packages/slate/test/commands/by-key/move-node-by-key/to-sibling.js
diff --git a/packages/slate/test/changes/by-key/remove-node-by-key/block.js b/packages/slate/test/commands/by-key/remove-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-node-by-key/block.js
rename to packages/slate/test/commands/by-key/remove-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/remove-node-by-key/inline.js b/packages/slate/test/commands/by-key/remove-node-by-key/inline.js
similarity index 82%
rename from packages/slate/test/changes/by-key/remove-node-by-key/inline.js
rename to packages/slate/test/commands/by-key/remove-node-by-key/inline.js
index af5846d85..18a38770e 100644
--- a/packages/slate/test/changes/by-key/remove-node-by-key/inline.js
+++ b/packages/slate/test/commands/by-key/remove-node-by-key/inline.js
@@ -10,7 +10,9 @@ export const input = (
+
one
+
two
@@ -20,7 +22,9 @@ export const input = (
export const output = (
-
+
+
+
two
diff --git a/packages/slate/test/changes/by-key/remove-node-by-key/selection-inside.js b/packages/slate/test/commands/by-key/remove-node-by-key/selection-inside.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-node-by-key/selection-inside.js
rename to packages/slate/test/commands/by-key/remove-node-by-key/selection-inside.js
diff --git a/packages/slate/test/changes/by-key/remove-node-by-key/text.js b/packages/slate/test/commands/by-key/remove-node-by-key/text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-node-by-key/text.js
rename to packages/slate/test/commands/by-key/remove-node-by-key/text.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/adjacent-non-void-inlines.js b/packages/slate/test/commands/by-key/remove-text-by-key/adjacent-non-void-inlines.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/adjacent-non-void-inlines.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/adjacent-non-void-inlines.js
diff --git a/packages/slate/test/operations/apply/remove-text/decoration-atomic-before.js b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-after-atomic.js
similarity index 55%
rename from packages/slate/test/operations/apply/remove-text/decoration-atomic-before.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/decoration-after-atomic.js
index 19726d9e8..bd4d22d7f 100644
--- a/packages/slate/test/operations/apply/remove-text/decoration-atomic-before.js
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-after-atomic.js
@@ -2,21 +2,21 @@
import h from '../../../helpers/h'
-export default [
- {
- type: 'remove_text',
- path: [0, 0],
- offset: 1,
- text: 'or',
- marks: [],
- },
-]
+export default function(change) {
+ change.removeTextByKey('a', 3, 1)
+}
+
+export const options = {
+ preserveDecorations: true,
+}
export const input = (
- w ord
+
+ wor d
+
@@ -26,7 +26,7 @@ export const output = (
- w d
+ wor
diff --git a/packages/slate/test/operations/apply/remove-text/decoration-atomic-after.js b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-before-atomic.js
similarity index 55%
rename from packages/slate/test/operations/apply/remove-text/decoration-atomic-after.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/decoration-before-atomic.js
index 6a911feb3..ba7e3d864 100644
--- a/packages/slate/test/operations/apply/remove-text/decoration-atomic-after.js
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-before-atomic.js
@@ -2,21 +2,21 @@
import h from '../../../helpers/h'
-export default [
- {
- type: 'remove_text',
- path: [0, 0],
- offset: 1,
- text: 'or',
- marks: [],
- },
-]
+export default function(change) {
+ change.removeTextByKey('a', 0, 1)
+}
+
+export const options = {
+ preserveDecorations: true,
+}
export const input = (
- word
+
+ wor d
+
@@ -26,7 +26,7 @@ export const output = (
- wd
+ or d
diff --git a/packages/slate/test/commands/by-key/remove-text-by-key/decoration-middle-atomic.js b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-middle-atomic.js
new file mode 100644
index 000000000..52d05f3e9
--- /dev/null
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/decoration-middle-atomic.js
@@ -0,0 +1,31 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export default function(change) {
+ change.removeTextByKey('a', 2, 1)
+}
+
+export const options = {
+ preserveDecorations: true,
+}
+
+export const input = (
+
+
+
+
+ wor d
+
+
+
+
+)
+
+export const output = (
+
+
+ wod
+
+
+)
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js b/packages/slate/test/commands/by-key/remove-text-by-key/inline-last-character.js
similarity index 77%
rename from packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/inline-last-character.js
index 6837f1b8b..8b7fa7bd5 100644
--- a/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/inline-last-character.js
@@ -10,9 +10,11 @@ export const input = (
+
a
+
@@ -22,7 +24,11 @@ export const output = (
-
+
+
+
+
+
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js b/packages/slate/test/commands/by-key/remove-text-by-key/inline-nested-last-character.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/inline-nested-last-character.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline-void.js b/packages/slate/test/commands/by-key/remove-text-by-key/inline-void.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/inline-void.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/inline-void.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline.js b/packages/slate/test/commands/by-key/remove-text-by-key/inline.js
similarity index 86%
rename from packages/slate/test/changes/by-key/remove-text-by-key/inline.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/inline.js
index 87037acc4..2dc429e2a 100644
--- a/packages/slate/test/changes/by-key/remove-text-by-key/inline.js
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/inline.js
@@ -10,9 +10,11 @@ export const input = (
+
word
+
@@ -22,7 +24,9 @@ export const output = (
+
wor
+
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/next-void-inline.js b/packages/slate/test/commands/by-key/remove-text-by-key/next-void-inline.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/next-void-inline.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/next-void-inline.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/previous-void-inline.js b/packages/slate/test/commands/by-key/remove-text-by-key/previous-void-inline.js
similarity index 84%
rename from packages/slate/test/changes/by-key/remove-text-by-key/previous-void-inline.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/previous-void-inline.js
index 310de2ba7..ab8a92fa1 100644
--- a/packages/slate/test/changes/by-key/remove-text-by-key/previous-void-inline.js
+++ b/packages/slate/test/commands/by-key/remove-text-by-key/previous-void-inline.js
@@ -10,9 +10,11 @@ export const input = (
+
a
two
+
@@ -22,8 +24,11 @@ export const output = (
+
+
two
+
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/selection-after.js b/packages/slate/test/commands/by-key/remove-text-by-key/selection-after.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/selection-after.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/selection-after.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/selection-before.js b/packages/slate/test/commands/by-key/remove-text-by-key/selection-before.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/selection-before.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/selection-before.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/selection-middle.js b/packages/slate/test/commands/by-key/remove-text-by-key/selection-middle.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/selection-middle.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/selection-middle.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/selection-start.js b/packages/slate/test/commands/by-key/remove-text-by-key/selection-start.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/selection-start.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/selection-start.js
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/text.js b/packages/slate/test/commands/by-key/remove-text-by-key/text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/remove-text-by-key/text.js
rename to packages/slate/test/commands/by-key/remove-text-by-key/text.js
diff --git a/packages/slate/test/changes/by-key/replace-node-by-key/block.js b/packages/slate/test/commands/by-key/replace-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-node-by-key/block.js
rename to packages/slate/test/commands/by-key/replace-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/replace-node-by-key/inline.js b/packages/slate/test/commands/by-key/replace-node-by-key/inline.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-node-by-key/inline.js
rename to packages/slate/test/commands/by-key/replace-node-by-key/inline.js
diff --git a/packages/slate/test/changes/by-key/replace-node-by-key/text.js b/packages/slate/test/commands/by-key/replace-node-by-key/text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-node-by-key/text.js
rename to packages/slate/test/commands/by-key/replace-node-by-key/text.js
diff --git a/packages/slate/test/changes/by-key/replace-text-by-key/replace-with-active-marks-with-data.js b/packages/slate/test/commands/by-key/replace-text-by-key/replace-with-active-marks-with-data.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-text-by-key/replace-with-active-marks-with-data.js
rename to packages/slate/test/commands/by-key/replace-text-by-key/replace-with-active-marks-with-data.js
diff --git a/packages/slate/test/changes/by-key/replace-text-by-key/replace-with-active-marks.js b/packages/slate/test/commands/by-key/replace-text-by-key/replace-with-active-marks.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-text-by-key/replace-with-active-marks.js
rename to packages/slate/test/commands/by-key/replace-text-by-key/replace-with-active-marks.js
diff --git a/packages/slate/test/changes/by-key/replace-text-by-key/replace-with-mark-and-active-mark.js b/packages/slate/test/commands/by-key/replace-text-by-key/replace-with-mark-and-active-mark.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-text-by-key/replace-with-mark-and-active-mark.js
rename to packages/slate/test/commands/by-key/replace-text-by-key/replace-with-mark-and-active-mark.js
diff --git a/packages/slate/test/changes/by-key/replace-text-by-key/replace-with-node-index-mark.js b/packages/slate/test/commands/by-key/replace-text-by-key/replace-with-node-index-mark.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-text-by-key/replace-with-node-index-mark.js
rename to packages/slate/test/commands/by-key/replace-text-by-key/replace-with-node-index-mark.js
diff --git a/packages/slate/test/changes/by-key/replace-text-by-key/replace-without-any-marks.js b/packages/slate/test/commands/by-key/replace-text-by-key/replace-without-any-marks.js
similarity index 100%
rename from packages/slate/test/changes/by-key/replace-text-by-key/replace-without-any-marks.js
rename to packages/slate/test/commands/by-key/replace-text-by-key/replace-without-any-marks.js
diff --git a/packages/slate/test/changes/by-key/set-mark-by-key/with-data.js b/packages/slate/test/commands/by-key/set-mark-by-key/with-data.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-mark-by-key/with-data.js
rename to packages/slate/test/commands/by-key/set-mark-by-key/with-data.js
diff --git a/packages/slate/test/changes/by-key/set-node-by-key/block.js b/packages/slate/test/commands/by-key/set-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-node-by-key/block.js
rename to packages/slate/test/commands/by-key/set-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js b/packages/slate/test/commands/by-key/set-node-by-key/inline-with-is-void.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js
rename to packages/slate/test/commands/by-key/set-node-by-key/inline-with-is-void.js
diff --git a/packages/slate/test/changes/by-key/set-node-by-key/string-shorthand.js b/packages/slate/test/commands/by-key/set-node-by-key/string-shorthand.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-node-by-key/string-shorthand.js
rename to packages/slate/test/commands/by-key/set-node-by-key/string-shorthand.js
diff --git a/packages/slate/test/changes/by-key/set-text-by-key/replace-with-string-and-mark.js b/packages/slate/test/commands/by-key/set-text-by-key/replace-with-string-and-mark.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-text-by-key/replace-with-string-and-mark.js
rename to packages/slate/test/commands/by-key/set-text-by-key/replace-with-string-and-mark.js
diff --git a/packages/slate/test/changes/by-key/set-text-by-key/replace-with-string.js b/packages/slate/test/commands/by-key/set-text-by-key/replace-with-string.js
similarity index 100%
rename from packages/slate/test/changes/by-key/set-text-by-key/replace-with-string.js
rename to packages/slate/test/commands/by-key/set-text-by-key/replace-with-string.js
diff --git a/packages/slate/test/changes/by-key/split-descendants-by-key/block-with-selection.js b/packages/slate/test/commands/by-key/split-descendants-by-key/block-with-selection.js
similarity index 100%
rename from packages/slate/test/changes/by-key/split-descendants-by-key/block-with-selection.js
rename to packages/slate/test/commands/by-key/split-descendants-by-key/block-with-selection.js
diff --git a/packages/slate/test/changes/by-key/split-descendants-by-key/block.js b/packages/slate/test/commands/by-key/split-descendants-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/split-descendants-by-key/block.js
rename to packages/slate/test/commands/by-key/split-descendants-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/split-node-by-key/block-with-selection.js b/packages/slate/test/commands/by-key/split-node-by-key/block-with-selection.js
similarity index 100%
rename from packages/slate/test/changes/by-key/split-node-by-key/block-with-selection.js
rename to packages/slate/test/commands/by-key/split-node-by-key/block-with-selection.js
diff --git a/packages/slate/test/changes/by-key/split-node-by-key/block.js b/packages/slate/test/commands/by-key/split-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/split-node-by-key/block.js
rename to packages/slate/test/commands/by-key/split-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-block-by-key/single-block.js b/packages/slate/test/commands/by-key/unwrap-block-by-key/single-block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-block-by-key/single-block.js
rename to packages/slate/test/commands/by-key/unwrap-block-by-key/single-block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-inline-by-key/single-block.js b/packages/slate/test/commands/by-key/unwrap-inline-by-key/single-block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-inline-by-key/single-block.js
rename to packages/slate/test/commands/by-key/unwrap-inline-by-key/single-block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-node-by-key/block.js b/packages/slate/test/commands/by-key/unwrap-node-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-node-by-key/block.js
rename to packages/slate/test/commands/by-key/unwrap-node-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-node-by-key/first-block.js b/packages/slate/test/commands/by-key/unwrap-node-by-key/first-block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-node-by-key/first-block.js
rename to packages/slate/test/commands/by-key/unwrap-node-by-key/first-block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-node-by-key/last-block.js b/packages/slate/test/commands/by-key/unwrap-node-by-key/last-block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-node-by-key/last-block.js
rename to packages/slate/test/commands/by-key/unwrap-node-by-key/last-block.js
diff --git a/packages/slate/test/changes/by-key/unwrap-node-by-key/middle-block.js b/packages/slate/test/commands/by-key/unwrap-node-by-key/middle-block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/unwrap-node-by-key/middle-block.js
rename to packages/slate/test/commands/by-key/unwrap-node-by-key/middle-block.js
diff --git a/packages/slate/test/changes/by-key/wrap-block-by-key/block.js b/packages/slate/test/commands/by-key/wrap-block-by-key/block.js
similarity index 100%
rename from packages/slate/test/changes/by-key/wrap-block-by-key/block.js
rename to packages/slate/test/commands/by-key/wrap-block-by-key/block.js
diff --git a/packages/slate/test/changes/by-key/wrap-block-by-key/text.js b/packages/slate/test/commands/by-key/wrap-block-by-key/text.js
similarity index 100%
rename from packages/slate/test/changes/by-key/wrap-block-by-key/text.js
rename to packages/slate/test/commands/by-key/wrap-block-by-key/text.js
diff --git a/packages/slate/test/changes/general/call/call-no-arguments.js b/packages/slate/test/commands/general/call/call-no-arguments.js
similarity index 100%
rename from packages/slate/test/changes/general/call/call-no-arguments.js
rename to packages/slate/test/commands/general/call/call-no-arguments.js
diff --git a/packages/slate/test/changes/general/call/call-with-arguments.js b/packages/slate/test/commands/general/call/call-with-arguments.js
similarity index 100%
rename from packages/slate/test/changes/general/call/call-with-arguments.js
rename to packages/slate/test/commands/general/call/call-with-arguments.js
diff --git a/packages/slate/test/changes/on-selection/blur/basic.js b/packages/slate/test/commands/on-selection/blur/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/blur/basic.js
rename to packages/slate/test/commands/on-selection/blur/basic.js
diff --git a/packages/slate/test/changes/on-selection/focus/basic.js b/packages/slate/test/commands/on-selection/focus/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/focus/basic.js
rename to packages/slate/test/commands/on-selection/focus/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-anchor/already-collapsed.js b/packages/slate/test/commands/on-selection/move-to-anchor/already-collapsed.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-anchor/already-collapsed.js
rename to packages/slate/test/commands/on-selection/move-to-anchor/already-collapsed.js
diff --git a/packages/slate/test/changes/on-selection/move-to-anchor/basic.js b/packages/slate/test/commands/on-selection/move-to-anchor/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-anchor/basic.js
rename to packages/slate/test/commands/on-selection/move-to-anchor/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-block/end.js b/packages/slate/test/commands/on-selection/move-to-end-of-block/end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-block/end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-block/end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-block/middle.js b/packages/slate/test/commands/on-selection/move-to-end-of-block/middle.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-block/middle.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-block/middle.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-block/start.js b/packages/slate/test/commands/on-selection/move-to-end-of-block/start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-block/start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-block/start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-document/block-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-document/block-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-document/block-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-document/block-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-document/block-middle.js b/packages/slate/test/commands/on-selection/move-to-end-of-document/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-document/block-middle.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-document/block-middle.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-document/block-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-document/block-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-document/block-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-document/block-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-document/document-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-document/document-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-document/document-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-document/document-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-document/document-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-document/document-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-document/document-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-document/document-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-middle.js b/packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-middle.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-middle.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-next-block/block-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-next-block/block-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-next-block/document-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-next-block/document-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-next-block/document-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-next-block/document-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-next-block/document-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-next-block/document-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-next-block/document-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-next-block/document-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-middle.js b/packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-middle.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-middle.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-previous-block/block-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-previous-block/block-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-previous-block/document-end.js b/packages/slate/test/commands/on-selection/move-to-end-of-previous-block/document-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-previous-block/document-end.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-previous-block/document-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end-of-previous-block/document-start.js b/packages/slate/test/commands/on-selection/move-to-end-of-previous-block/document-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end-of-previous-block/document-start.js
rename to packages/slate/test/commands/on-selection/move-to-end-of-previous-block/document-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end/already-collapsed.js b/packages/slate/test/commands/on-selection/move-to-end/already-collapsed.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end/already-collapsed.js
rename to packages/slate/test/commands/on-selection/move-to-end/already-collapsed.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end/basic.js b/packages/slate/test/commands/on-selection/move-to-end/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end/basic.js
rename to packages/slate/test/commands/on-selection/move-to-end/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-end/void.js b/packages/slate/test/commands/on-selection/move-to-end/void.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-end/void.js
rename to packages/slate/test/commands/on-selection/move-to-end/void.js
diff --git a/packages/slate/test/changes/on-selection/move-to-focus/already-collapsed.js b/packages/slate/test/commands/on-selection/move-to-focus/already-collapsed.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-focus/already-collapsed.js
rename to packages/slate/test/commands/on-selection/move-to-focus/already-collapsed.js
diff --git a/packages/slate/test/changes/on-selection/move-to-focus/basic.js b/packages/slate/test/commands/on-selection/move-to-focus/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-focus/basic.js
rename to packages/slate/test/commands/on-selection/move-to-focus/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-range-of-document/basic.js b/packages/slate/test/commands/on-selection/move-to-range-of-document/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-range-of-document/basic.js
rename to packages/slate/test/commands/on-selection/move-to-range-of-document/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start-of-document/block-end.js b/packages/slate/test/commands/on-selection/move-to-start-of-document/block-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start-of-document/block-end.js
rename to packages/slate/test/commands/on-selection/move-to-start-of-document/block-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start-of-document/block-middle.js b/packages/slate/test/commands/on-selection/move-to-start-of-document/block-middle.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start-of-document/block-middle.js
rename to packages/slate/test/commands/on-selection/move-to-start-of-document/block-middle.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start-of-document/block-start.js b/packages/slate/test/commands/on-selection/move-to-start-of-document/block-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start-of-document/block-start.js
rename to packages/slate/test/commands/on-selection/move-to-start-of-document/block-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start-of-document/document-end.js b/packages/slate/test/commands/on-selection/move-to-start-of-document/document-end.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start-of-document/document-end.js
rename to packages/slate/test/commands/on-selection/move-to-start-of-document/document-end.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start-of-document/document-start.js b/packages/slate/test/commands/on-selection/move-to-start-of-document/document-start.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start-of-document/document-start.js
rename to packages/slate/test/commands/on-selection/move-to-start-of-document/document-start.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start/already-collapsed.js b/packages/slate/test/commands/on-selection/move-to-start/already-collapsed.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start/already-collapsed.js
rename to packages/slate/test/commands/on-selection/move-to-start/already-collapsed.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start/basic.js b/packages/slate/test/commands/on-selection/move-to-start/basic.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start/basic.js
rename to packages/slate/test/commands/on-selection/move-to-start/basic.js
diff --git a/packages/slate/test/changes/on-selection/move-to-start/void.js b/packages/slate/test/commands/on-selection/move-to-start/void.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/move-to-start/void.js
rename to packages/slate/test/commands/on-selection/move-to-start/void.js
diff --git a/packages/slate/test/changes/on-selection/select/with-object.js b/packages/slate/test/commands/on-selection/select/with-object.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/select/with-object.js
rename to packages/slate/test/commands/on-selection/select/with-object.js
diff --git a/packages/slate/test/changes/on-selection/select/with-selection.js b/packages/slate/test/commands/on-selection/select/with-selection.js
similarity index 100%
rename from packages/slate/test/changes/on-selection/select/with-selection.js
rename to packages/slate/test/commands/on-selection/select/with-selection.js
diff --git a/packages/slate/test/changes/on-state/set-data/simple.js b/packages/slate/test/commands/on-state/set-data/simple.js
similarity index 100%
rename from packages/slate/test/changes/on-state/set-data/simple.js
rename to packages/slate/test/commands/on-state/set-data/simple.js
diff --git a/packages/slate/test/history/undo/add-mark-across-blocks.js b/packages/slate/test/history/undo/add-mark-across-blocks.js
index 4a5902394..aa0fb3af4 100644
--- a/packages/slate/test/history/undo/add-mark-across-blocks.js
+++ b/packages/slate/test/history/undo/add-mark-across-blocks.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .addMark('bold')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.addMark('bold')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/add-mark-across-marks.js b/packages/slate/test/history/undo/add-mark-across-marks.js
index 4e029333e..b125bd02f 100644
--- a/packages/slate/test/history/undo/add-mark-across-marks.js
+++ b/packages/slate/test/history/undo/add-mark-across-marks.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .addMark('bold')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.addMark('bold')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/add-mark-across-same-mark.js b/packages/slate/test/history/undo/add-mark-across-same-mark.js
index d26b971fb..1fba6210a 100644
--- a/packages/slate/test/history/undo/add-mark-across-same-mark.js
+++ b/packages/slate/test/history/undo/add-mark-across-same-mark.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .addMark('bold')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.addMark('bold')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/add-mark.js b/packages/slate/test/history/undo/add-mark.js
index a7e4e272c..dd05733b5 100644
--- a/packages/slate/test/history/undo/add-mark.js
+++ b/packages/slate/test/history/undo/add-mark.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .addMark('bold')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.addMark('bold')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/delete-across-blocks.js b/packages/slate/test/history/undo/delete-across-blocks.js
index 46e0c4bbd..c8d0b2fcd 100644
--- a/packages/slate/test/history/undo/delete-across-blocks.js
+++ b/packages/slate/test/history/undo/delete-across-blocks.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .delete()
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.delete()
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
// the paragraph and code blocks have some random data
diff --git a/packages/slate/test/history/undo/delete-across-inlines.js b/packages/slate/test/history/undo/delete-across-inlines.js
index d66e375c2..b393f5220 100644
--- a/packages/slate/test/history/undo/delete-across-inlines.js
+++ b/packages/slate/test/history/undo/delete-across-inlines.js
@@ -2,26 +2,32 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .delete()
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.delete()
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
+
o ne
+
+
tw o
+
diff --git a/packages/slate/test/history/undo/delete-across-marks.js b/packages/slate/test/history/undo/delete-across-marks.js
index 3b66970e6..f15bdf427 100644
--- a/packages/slate/test/history/undo/delete-across-marks.js
+++ b/packages/slate/test/history/undo/delete-across-marks.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .delete()
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.delete()
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/delete.js b/packages/slate/test/history/undo/delete.js
index d16ac1d01..9edf1ff5a 100644
--- a/packages/slate/test/history/undo/delete.js
+++ b/packages/slate/test/history/undo/delete.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .delete()
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.delete()
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/insert-block.js b/packages/slate/test/history/undo/insert-block.js
index 5b7eed03a..0983dc776 100644
--- a/packages/slate/test/history/undo/insert-block.js
+++ b/packages/slate/test/history/undo/insert-block.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .insertBlock('quote')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.insertBlock('quote')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/insert-text-contiguous.js b/packages/slate/test/history/undo/insert-text-contiguous.js
index 08cf2a857..268674685 100644
--- a/packages/slate/test/history/undo/insert-text-contiguous.js
+++ b/packages/slate/test/history/undo/insert-text-contiguous.js
@@ -2,16 +2,22 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .insertText('t')
- .value.change()
- .insertText('w')
- .value.change()
- .insertText('o')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.insertText('t')
+ })
+
+ editor.change(change => {
+ change.insertText('w')
+ })
+
+ editor.change(change => {
+ change.insertText('o')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/insert-text-not-contiguous.js b/packages/slate/test/history/undo/insert-text-not-contiguous.js
index 0cc240349..c737946cf 100644
--- a/packages/slate/test/history/undo/insert-text-not-contiguous.js
+++ b/packages/slate/test/history/undo/insert-text-not-contiguous.js
@@ -2,18 +2,22 @@
import h from '../../helpers/h'
-export default function(value) {
- const a = value.change().insertText('t').value
- const b = a
- .change()
- .moveBackward(1)
- .insertText('w').value
- const c = b
- .change()
- .moveBackward(1)
- .insertText('o').value
- const d = c.change().undo().value
- return d
+export default function(editor) {
+ editor.change(change => {
+ change.insertText('t')
+ })
+
+ editor.change(change => {
+ change.moveBackward(1).insertText('w')
+ })
+
+ editor.change(change => {
+ change.moveBackward(1).insertText('o')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/insert-text.js b/packages/slate/test/history/undo/insert-text.js
index ba45234f6..48e6dc79c 100644
--- a/packages/slate/test/history/undo/insert-text.js
+++ b/packages/slate/test/history/undo/insert-text.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .insertText('text')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.insertText('text')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/move-node-affecting-path.js b/packages/slate/test/history/undo/move-node-affecting-path.js
index bde344391..97f5951c5 100644
--- a/packages/slate/test/history/undo/move-node-affecting-path.js
+++ b/packages/slate/test/history/undo/move-node-affecting-path.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .moveNodeByKey('c', 'd', 1)
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.moveNodeByKey('c', 'd', 1)
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/move-node-before-itself.js b/packages/slate/test/history/undo/move-node-before-itself.js
index 37d754b4e..f7aa88bda 100644
--- a/packages/slate/test/history/undo/move-node-before-itself.js
+++ b/packages/slate/test/history/undo/move-node-before-itself.js
@@ -2,10 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- const next = value.change().moveNodeByKey('h', 'a', 0).value
- const undo = next.change().undo().value
- return undo
+export default function(editor) {
+ editor.change(change => {
+ change.moveNodeByKey('h', 'a', 0)
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/move-node-by-key.js b/packages/slate/test/history/undo/move-node-by-key.js
index 543f1b2d9..358e27800 100644
--- a/packages/slate/test/history/undo/move-node-by-key.js
+++ b/packages/slate/test/history/undo/move-node-by-key.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .moveNodeByKey('b', 'a', 1)
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.moveNodeByKey('b', 'a', 1)
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/remove-mark.js b/packages/slate/test/history/undo/remove-mark.js
index ca05f4cab..18a07026f 100644
--- a/packages/slate/test/history/undo/remove-mark.js
+++ b/packages/slate/test/history/undo/remove-mark.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .removeMark('bold')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.removeMark('bold')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/remove-node-by-key.js b/packages/slate/test/history/undo/remove-node-by-key.js
index 56ed73b60..1efb03e50 100644
--- a/packages/slate/test/history/undo/remove-node-by-key.js
+++ b/packages/slate/test/history/undo/remove-node-by-key.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .removeNodeByKey('a')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.removeNodeByKey('a')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/remove-text.js b/packages/slate/test/history/undo/remove-text.js
index 6c9f224bc..3253610cf 100644
--- a/packages/slate/test/history/undo/remove-text.js
+++ b/packages/slate/test/history/undo/remove-text.js
@@ -2,14 +2,17 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .moveAnchorForward(4)
- .moveFocusForward(7)
- .delete()
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change
+ .moveAnchorForward(4)
+ .moveFocusForward(7)
+ .delete()
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/set-node-by-key-with-data.js b/packages/slate/test/history/undo/set-node-by-key-with-data.js
index fee0f8a99..bf5ee2a6b 100644
--- a/packages/slate/test/history/undo/set-node-by-key-with-data.js
+++ b/packages/slate/test/history/undo/set-node-by-key-with-data.js
@@ -2,14 +2,16 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .setNodeByKey('a', {
+export default function(editor) {
+ editor.change(change => {
+ change.setNodeByKey('a', {
data: { thing: 'value' },
})
- .value.change()
- .undo().value
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/split-node-by-key-block.js b/packages/slate/test/history/undo/split-node-by-key-block.js
index 6874a8b50..508886a42 100644
--- a/packages/slate/test/history/undo/split-node-by-key-block.js
+++ b/packages/slate/test/history/undo/split-node-by-key-block.js
@@ -2,21 +2,27 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .splitNodeByKey('a', 2)
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.splitNodeByKey('a', 2)
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
+
one
-
+
+
+
two
+
diff --git a/packages/slate/test/history/undo/unwrap-node-by-key.js b/packages/slate/test/history/undo/unwrap-node-by-key.js
index a6f01df37..bb7d7d5c2 100644
--- a/packages/slate/test/history/undo/unwrap-node-by-key.js
+++ b/packages/slate/test/history/undo/unwrap-node-by-key.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .unwrapNodeByKey('a')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.unwrapNodeByKey('a')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/history/undo/wrap-inline-across-blocks.js b/packages/slate/test/history/undo/wrap-inline-across-blocks.js
index 1a1601a59..4b3000cc9 100644
--- a/packages/slate/test/history/undo/wrap-inline-across-blocks.js
+++ b/packages/slate/test/history/undo/wrap-inline-across-blocks.js
@@ -2,12 +2,14 @@
import h from '../../helpers/h'
-export default function(value) {
- return value
- .change()
- .wrapInline('hashtag')
- .value.change()
- .undo().value
+export default function(editor) {
+ editor.change(change => {
+ change.wrapInline('hashtag')
+ })
+
+ editor.change(change => {
+ change.undo()
+ })
}
export const input = (
diff --git a/packages/slate/test/index.js b/packages/slate/test/index.js
index 1de32d191..fe41486b5 100644
--- a/packages/slate/test/index.js
+++ b/packages/slate/test/index.js
@@ -1,6 +1,28 @@
import assert from 'assert'
import { fixtures } from 'slate-dev-test-utils'
-import { Node, Schema, Value } from 'slate'
+import { Node, Editor, Value } from 'slate'
+
+const plugins = [
+ {
+ schema: {
+ blocks: {
+ image: {
+ isVoid: true,
+ },
+ },
+ inlines: {
+ emoji: {
+ isVoid: true,
+ },
+ },
+ marks: {
+ result: {
+ isAtomic: true,
+ },
+ },
+ },
+ },
+]
describe('slate', () => {
fixtures(__dirname, 'models/leaf', ({ module }) => {
@@ -53,56 +75,65 @@ describe('slate', () => {
fixtures(__dirname, 'operations', ({ module }) => {
const { input, output } = module
const operations = module.default
- const change = input.change()
- change.applyOperations(operations)
+ const editor = new Editor({ plugins })
+
const opts = {
preserveSelection: true,
preserveDecorations: true,
- preserveData: true,
}
- const actual = change.value.toJSON(opts)
- const expected = output.toJSON(opts)
+
+ editor.setValue(input)
+
+ editor.change(change => {
+ change.applyOperations(operations)
+ })
+
+ const actual = editor.value.toJSON(opts)
+
+ editor.setValue(output)
+ const expected = editor.value.toJSON(opts)
assert.deepEqual(actual, expected)
})
- fixtures(__dirname, 'changes', ({ module }) => {
- const { input, output } = module
+ // The hyperscript editor has the schema, but the test
+ // editor doesn't! It needs to live in the tests instead.
+
+ fixtures(__dirname, 'commands', ({ module }) => {
+ const { input, output, options = {} } = module
const fn = module.default
- const change = input.change()
- fn(change)
- const opts = { preserveSelection: true, preserveData: true }
- const actual = change.value.toJSON(opts)
- const expected = output.toJSON(opts)
+ const editor = new Editor({ plugins })
+ const opts = { preserveSelection: true, ...options }
+
+ editor.setValue(input)
+ editor.change(fn)
+ const actual = editor.value.toJSON(opts)
+
+ editor.setValue(output)
+ const expected = editor.value.toJSON(opts)
assert.deepEqual(actual, expected)
})
fixtures(__dirname, 'schema', ({ module }) => {
- let { input, output, schema } = module
- const s = Schema.create(schema)
-
- if (!Value.isValue(input)) {
- input = Value.fromJSON(input)
- }
-
- let expected = output
- let actual = input
- .change()
- .setValue({ schema: s })
- .normalize().value
-
- if (Value.isValue(actual)) actual = actual.toJSON()
- if (Value.isValue(expected)) expected = expected.toJSON()
-
+ const { input, output, schema } = module
+ const editor = new Editor({ value: input, plugins: [{ schema }] })
+ const actual = editor.value.toJSON()
+ const expected = output.toJSON()
assert.deepEqual(actual, expected)
})
fixtures(__dirname, 'history', ({ module }) => {
const { input, output } = module
const fn = module.default
- const next = fn(input)
- const opts = { preserveSelection: true, preserveData: true }
- const actual = next.toJSON(opts)
+ const editor = new Editor({ plugins })
+ const opts = { preserveSelection: true }
+
+ editor.setValue(input)
+ fn(editor)
+ const actual = editor.value.toJSON(opts)
+
+ editor.setValue(output)
const expected = output.toJSON(opts)
+
assert.deepEqual(actual, expected)
})
})
diff --git a/packages/slate/test/models/text/delete/across-leaves/connectable-after-remove.js b/packages/slate/test/models/text/delete/across-leaves/connectable-after-remove.js
index d2a46fd55..95aba59f3 100644
--- a/packages/slate/test/models/text/delete/across-leaves/connectable-after-remove.js
+++ b/packages/slate/test/models/text/delete/across-leaves/connectable-after-remove.js
@@ -6,7 +6,7 @@ export const input = (
Cat is very very Cute
-)[0]
+)
export default function(t) {
return t.removeText(6, 9)
@@ -16,4 +16,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/delete/across-leaves/in-connectable-after-remove.js b/packages/slate/test/models/text/delete/across-leaves/in-connectable-after-remove.js
index 070771c25..128978901 100644
--- a/packages/slate/test/models/text/delete/across-leaves/in-connectable-after-remove.js
+++ b/packages/slate/test/models/text/delete/across-leaves/in-connectable-after-remove.js
@@ -6,7 +6,7 @@ export const input = (
Cat is very very Cute
-)[0]
+)
export default function(t) {
return t.removeText(6, 9)
@@ -17,4 +17,4 @@ export const output = (
Cat is
Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/delete/all-text-length/differently-marked-text.js b/packages/slate/test/models/text/delete/all-text-length/differently-marked-text.js
index 380753a17..7cab36397 100644
--- a/packages/slate/test/models/text/delete/all-text-length/differently-marked-text.js
+++ b/packages/slate/test/models/text/delete/all-text-length/differently-marked-text.js
@@ -6,10 +6,10 @@ export const input = (
Cat is Cute
-)[0]
+)
export default function(t) {
return t.removeText(0, t.text.length)
}
-export const output = [0]
+export const output =
diff --git a/packages/slate/test/models/text/delete/all-text-length/marked-text.js b/packages/slate/test/models/text/delete/all-text-length/marked-text.js
index ba6b9697a..57d12858d 100644
--- a/packages/slate/test/models/text/delete/all-text-length/marked-text.js
+++ b/packages/slate/test/models/text/delete/all-text-length/marked-text.js
@@ -2,10 +2,18 @@
import h from '../../../../helpers/h'
-export const input = Cat is Cute [0]
+export const input = (
+
+ Cat is Cute
+
+)
export default function(t) {
return t.removeText(0, t.text.length)
}
-export const output = [0]
+export const output = (
+
+
+
+)
diff --git a/packages/slate/test/models/text/delete/all-text-length/partial-marked-text.js b/packages/slate/test/models/text/delete/all-text-length/partial-marked-text.js
index 4b6ca177f..4e718bc6d 100644
--- a/packages/slate/test/models/text/delete/all-text-length/partial-marked-text.js
+++ b/packages/slate/test/models/text/delete/all-text-length/partial-marked-text.js
@@ -3,13 +3,19 @@
import h from '../../../../helpers/h'
export const input = (
-
- Cat is Cute
-
-)[0]
+
+
+ Cat is Cute
+
+
+)
export default function(t) {
return t.removeText(0, t.text.length)
}
-export const output = [0]
+export const output = (
+
+
+
+)
diff --git a/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char-with-mark.js b/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char-with-mark.js
index 9b820f6a9..83eb32e36 100644
--- a/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char-with-mark.js
+++ b/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char-with-mark.js
@@ -6,7 +6,7 @@ export const input = (
Cat is Cute
-)[0]
+)
export default function(t) {
return t.removeText(4, 1)
@@ -16,4 +16,4 @@ export const output = (
Cat s Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char.js b/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char.js
index c4d0fc1d6..01bf63bc3 100644
--- a/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char.js
+++ b/packages/slate/test/models/text/delete/inside-a-leaf/delete-a-char.js
@@ -6,7 +6,7 @@ export const input = (
Catt is Cute
-)[0]
+)
export default function(t) {
return t.removeText(3, 1)
@@ -16,4 +16,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-end/pure-text-after-marked-text.js b/packages/slate/test/models/text/insert/from-end/pure-text-after-marked-text.js
index 74787561a..0fec67b78 100644
--- a/packages/slate/test/models/text/insert/from-end/pure-text-after-marked-text.js
+++ b/packages/slate/test/models/text/insert/from-end/pure-text-after-marked-text.js
@@ -7,7 +7,7 @@ export const input = (
Cat
Cute
-)[0]
+)
export default function(t) {
return t.insertText(3, ' is')
@@ -17,4 +17,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-end/pure-text-after-pure-text.js b/packages/slate/test/models/text/insert/from-end/pure-text-after-pure-text.js
index 86e3e96fd..b32077f89 100644
--- a/packages/slate/test/models/text/insert/from-end/pure-text-after-pure-text.js
+++ b/packages/slate/test/models/text/insert/from-end/pure-text-after-pure-text.js
@@ -6,7 +6,7 @@ export const input = (
Cat Cute
-)[0]
+)
export default function(t) {
return t.insertText(3, ' is')
@@ -16,4 +16,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-end/pure-text-at-end-of-all-text.js b/packages/slate/test/models/text/insert/from-end/pure-text-at-end-of-all-text.js
index d3dc04f6c..f30431c87 100644
--- a/packages/slate/test/models/text/insert/from-end/pure-text-at-end-of-all-text.js
+++ b/packages/slate/test/models/text/insert/from-end/pure-text-at-end-of-all-text.js
@@ -6,7 +6,7 @@ export const input = (
Cat is
-)[0]
+)
export default function(t) {
return t.insertText(6, ' Cute')
@@ -16,4 +16,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-marked-text.js b/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-marked-text.js
index 0c3b6de14..dad93cdcc 100644
--- a/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-marked-text.js
+++ b/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-marked-text.js
@@ -4,14 +4,20 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = CatCute [0]
+export const input = (
+
+ CatCute
+
+)
export default function(t) {
return t.insertText(3, ' is ', Set.of(Mark.create('bold')))
}
export const output = (
-
- Cat is Cute
-
-)[0]
+
+
+ Cat is Cute
+
+
+)
diff --git a/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-pure-text.js b/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-pure-text.js
index c91434da9..34f1a52a3 100644
--- a/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-pure-text.js
+++ b/packages/slate/test/models/text/insert/from-middle/marked-text-in-middle-of-pure-text.js
@@ -4,7 +4,7 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = CatCute [0]
+export const input = CatCute
export default function(t) {
return t.insertText(3, ' is ', Set.of(Mark.create('bold')))
@@ -14,4 +14,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-middle/pure-text-into-middle-of-marks.js b/packages/slate/test/models/text/insert/from-middle/pure-text-into-middle-of-marks.js
index d0e17e190..3b74d5cf2 100644
--- a/packages/slate/test/models/text/insert/from-middle/pure-text-into-middle-of-marks.js
+++ b/packages/slate/test/models/text/insert/from-middle/pure-text-into-middle-of-marks.js
@@ -6,7 +6,7 @@ export const input = (
CatCute
-)[0]
+)
export default function(t) {
return t.insertText(3, ' is ')
@@ -16,4 +16,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-middle/pure-text.js b/packages/slate/test/models/text/insert/from-middle/pure-text.js
index 86802684a..a95cf73df 100644
--- a/packages/slate/test/models/text/insert/from-middle/pure-text.js
+++ b/packages/slate/test/models/text/insert/from-middle/pure-text.js
@@ -2,10 +2,10 @@
import h from '../../../../helpers/h'
-export const input = CatCute [0]
+export const input = CatCute
export default function(t) {
return t.insertText(3, ' is ')
}
-export const output = Cat is Cute [0]
+export const output = Cat is Cute
diff --git a/packages/slate/test/models/text/insert/from-start/marked-text-on-null-text.js b/packages/slate/test/models/text/insert/from-start/marked-text-on-null-text.js
index d33b0878f..bf4c6d6f3 100644
--- a/packages/slate/test/models/text/insert/from-start/marked-text-on-null-text.js
+++ b/packages/slate/test/models/text/insert/from-start/marked-text-on-null-text.js
@@ -4,7 +4,11 @@ import { List } from 'immutable'
import { Mark } from 'slate'
import h from '../../../../helpers/h'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.insertText(0, 'Cat is Cute', List.of(Mark.create({ type: 'bold' })))
@@ -14,4 +18,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text-at-invalid-offset.js b/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text-at-invalid-offset.js
index c7b264ab1..4316a0029 100644
--- a/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text-at-invalid-offset.js
+++ b/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text-at-invalid-offset.js
@@ -2,10 +2,10 @@
import h from '../../../../helpers/h'
-export const input = [0]
+export const input =
export default function(t) {
return t.insertText(1, 'Cat is Cute')
}
-export const output = Cat is Cute [0]
+export const output = Cat is Cute
diff --git a/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text.js b/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text.js
index b7b8f77ee..d4ff0dccc 100644
--- a/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text.js
+++ b/packages/slate/test/models/text/insert/from-start/pure-text-on-null-text.js
@@ -2,10 +2,10 @@
import h from '../../../../helpers/h'
-export const input = [0]
+export const input =
export default function(t) {
return t.insertText(0, 'Cat is Cute')
}
-export const output = Cat is Cute [0]
+export const output = Cat is Cute
diff --git a/packages/slate/test/models/text/marks/add-marks/to-affect-nothing.js b/packages/slate/test/models/text/marks/add-marks/to-affect-nothing.js
index 5058ae780..40782d04a 100644
--- a/packages/slate/test/models/text/marks/add-marks/to-affect-nothing.js
+++ b/packages/slate/test/models/text/marks/add-marks/to-affect-nothing.js
@@ -7,7 +7,7 @@ export const input = (
Cat is Cute
-)[0]
+)
export default function(t) {
return t.addMark(3, 4, Mark.create('bold'))
@@ -17,4 +17,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/add-marks/to-cover-whole-text.js b/packages/slate/test/models/text/marks/add-marks/to-cover-whole-text.js
index 5a51b64a8..c84c4bb18 100644
--- a/packages/slate/test/models/text/marks/add-marks/to-cover-whole-text.js
+++ b/packages/slate/test/models/text/marks/add-marks/to-cover-whole-text.js
@@ -3,7 +3,7 @@
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = Cat is Cute [0]
+export const input = Cat is Cute
export default function(t) {
return t.addMark(0, t.text.length, Mark.create('italic'))
@@ -13,4 +13,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/add-marks/to-merge-two-leaves.js b/packages/slate/test/models/text/marks/add-marks/to-merge-two-leaves.js
index 2d6b4248c..7284fec6d 100644
--- a/packages/slate/test/models/text/marks/add-marks/to-merge-two-leaves.js
+++ b/packages/slate/test/models/text/marks/add-marks/to-merge-two-leaves.js
@@ -8,7 +8,7 @@ export const input = (
Cat is
Cute
-)[0]
+)
export default function(t) {
return t.addMark(3, 3, Mark.create('bold'))
@@ -18,4 +18,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/add-marks/to-split-leaves.js b/packages/slate/test/models/text/marks/add-marks/to-split-leaves.js
index c1d1d8b10..748bb82aa 100644
--- a/packages/slate/test/models/text/marks/add-marks/to-split-leaves.js
+++ b/packages/slate/test/models/text/marks/add-marks/to-split-leaves.js
@@ -8,7 +8,7 @@ export const input = (
Cat i
s Cute
-)[0]
+)
export default function(t) {
return t.addMark(3, 4, Mark.create('italic'))
@@ -22,4 +22,4 @@ export const output = (
Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-at-leaf-end.js b/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-at-leaf-end.js
index 481c9f904..8ddc57090 100644
--- a/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-at-leaf-end.js
+++ b/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-at-leaf-end.js
@@ -11,7 +11,7 @@ export const input = (
is Cute
-)[0]
+)
export default function(t) {
return t.getActiveMarksBetweenOffsets(0, 6)
diff --git a/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-with-totally-different-marks.js b/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-with-totally-different-marks.js
index 4b65d206f..a89b2e160 100644
--- a/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-with-totally-different-marks.js
+++ b/packages/slate/test/models/text/marks/get-active-marks-between/marked-text-with-totally-different-marks.js
@@ -8,7 +8,7 @@ export const input = (
Cat
is Cute
-)[0]
+)
export default function(t) {
return t.getActiveMarksBetweenOffsets(0, 6)
diff --git a/packages/slate/test/models/text/marks/get-active-marks-between/null-marked-text.js b/packages/slate/test/models/text/marks/get-active-marks-between/null-marked-text.js
index 8a274a718..201bd1503 100644
--- a/packages/slate/test/models/text/marks/get-active-marks-between/null-marked-text.js
+++ b/packages/slate/test/models/text/marks/get-active-marks-between/null-marked-text.js
@@ -4,7 +4,11 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.getActiveMarksBetweenOffsets(0, 0)
diff --git a/packages/slate/test/models/text/marks/get-active-marks/adject-same-marks.js b/packages/slate/test/models/text/marks/get-active-marks/adject-same-marks.js
index eda1b2629..05a0e036b 100644
--- a/packages/slate/test/models/text/marks/get-active-marks/adject-same-marks.js
+++ b/packages/slate/test/models/text/marks/get-active-marks/adject-same-marks.js
@@ -11,7 +11,7 @@ export const input = (
Cute
-)[0]
+)
export default function(t) {
return t.getActiveMarks()
diff --git a/packages/slate/test/models/text/marks/get-active-marks/intersecting-marks-text.js b/packages/slate/test/models/text/marks/get-active-marks/intersecting-marks-text.js
index 367ee9f74..68098ca7c 100644
--- a/packages/slate/test/models/text/marks/get-active-marks/intersecting-marks-text.js
+++ b/packages/slate/test/models/text/marks/get-active-marks/intersecting-marks-text.js
@@ -16,7 +16,7 @@ export const input = (
g
-)[0]
+)
export default function(t) {
return t.getActiveMarks()
diff --git a/packages/slate/test/models/text/marks/get-active-marks/marked-text.js b/packages/slate/test/models/text/marks/get-active-marks/marked-text.js
index 689ab4182..10597169c 100644
--- a/packages/slate/test/models/text/marks/get-active-marks/marked-text.js
+++ b/packages/slate/test/models/text/marks/get-active-marks/marked-text.js
@@ -11,7 +11,7 @@ export const input = (
Cute
-)[0]
+)
export default function(t) {
return t.getActiveMarks()
diff --git a/packages/slate/test/models/text/marks/get-active-marks/partially-marked-text.js b/packages/slate/test/models/text/marks/get-active-marks/partially-marked-text.js
index 49e45bb26..26cb453a5 100644
--- a/packages/slate/test/models/text/marks/get-active-marks/partially-marked-text.js
+++ b/packages/slate/test/models/text/marks/get-active-marks/partially-marked-text.js
@@ -9,7 +9,7 @@ export const input = (
is
Cute
-)[0]
+)
export default function(t) {
return t.getActiveMarks()
diff --git a/packages/slate/test/models/text/marks/get-marks-at-index/null-marked-text.js b/packages/slate/test/models/text/marks/get-marks-at-index/null-marked-text.js
index bd08bac28..8d589c3ef 100644
--- a/packages/slate/test/models/text/marks/get-marks-at-index/null-marked-text.js
+++ b/packages/slate/test/models/text/marks/get-marks-at-index/null-marked-text.js
@@ -4,7 +4,11 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.getMarksAtIndex(0)
diff --git a/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-leaf-end.js b/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-leaf-end.js
index 0873a318e..3a5930610 100644
--- a/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-leaf-end.js
+++ b/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-leaf-end.js
@@ -9,7 +9,7 @@ export const input = (
Cat
is Cute
-)[0]
+)
export default function(t) {
return t.getMarksBetweenOffsets(0, 6)
diff --git a/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-many-leaves.js b/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-many-leaves.js
index 4e5d14717..07eee7795 100644
--- a/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-many-leaves.js
+++ b/packages/slate/test/models/text/marks/get-marks-between/marked-text-with-many-leaves.js
@@ -16,7 +16,7 @@ export const input = (
is
Cat
-)[0]
+)
export default function(t) {
return t.getMarksBetweenOffsets(0, 12)
diff --git a/packages/slate/test/models/text/marks/get-marks-between/null-marked-text.js b/packages/slate/test/models/text/marks/get-marks-between/null-marked-text.js
index 85272bb9a..c82164dd7 100644
--- a/packages/slate/test/models/text/marks/get-marks-between/null-marked-text.js
+++ b/packages/slate/test/models/text/marks/get-marks-between/null-marked-text.js
@@ -4,7 +4,11 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.getMarksBetweenOffsets(0, 0)
diff --git a/packages/slate/test/models/text/marks/get-marks/marked-text.js b/packages/slate/test/models/text/marks/get-marks/marked-text.js
index 63367d94f..ab822d523 100644
--- a/packages/slate/test/models/text/marks/get-marks/marked-text.js
+++ b/packages/slate/test/models/text/marks/get-marks/marked-text.js
@@ -10,7 +10,7 @@ export const input = (
is
Cute
-)[0]
+)
export default function(t) {
return t.getMarks()
diff --git a/packages/slate/test/models/text/marks/get-marks/null-text-with-marks.js b/packages/slate/test/models/text/marks/get-marks/null-text-with-marks.js
index 48ff197e7..8c50690de 100644
--- a/packages/slate/test/models/text/marks/get-marks/null-text-with-marks.js
+++ b/packages/slate/test/models/text/marks/get-marks/null-text-with-marks.js
@@ -4,7 +4,11 @@ import { Set } from 'immutable'
import h from '../../../../helpers/h'
import { Mark } from 'slate'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.getMarks()
diff --git a/packages/slate/test/models/text/marks/get-marks/null-text.js b/packages/slate/test/models/text/marks/get-marks/null-text.js
index f2bc27afa..4ae383d2b 100644
--- a/packages/slate/test/models/text/marks/get-marks/null-text.js
+++ b/packages/slate/test/models/text/marks/get-marks/null-text.js
@@ -3,7 +3,7 @@
import h from '../../../../helpers/h'
import { Set } from 'immutable'
-export const input = [0]
+export const input =
export default function(t) {
return t.getMarks()
diff --git a/packages/slate/test/models/text/marks/get-marks/partially-marked-text.js b/packages/slate/test/models/text/marks/get-marks/partially-marked-text.js
index a2fe8620a..fa5cd0945 100644
--- a/packages/slate/test/models/text/marks/get-marks/partially-marked-text.js
+++ b/packages/slate/test/models/text/marks/get-marks/partially-marked-text.js
@@ -10,7 +10,7 @@ export const input = (
is
Cute
-)[0]
+)
export default function(t) {
return t.getMarks()
diff --git a/packages/slate/test/models/text/marks/get-marks/plain-text.js b/packages/slate/test/models/text/marks/get-marks/plain-text.js
index 201662d76..44470fd63 100644
--- a/packages/slate/test/models/text/marks/get-marks/plain-text.js
+++ b/packages/slate/test/models/text/marks/get-marks/plain-text.js
@@ -3,7 +3,7 @@
import h from '../../../../helpers/h'
import { Set } from 'immutable'
-export const input = Cat is Cute [0]
+export const input = Cat is Cute
export default function(t) {
return t.getMarks()
diff --git a/packages/slate/test/models/text/marks/remove-mark/remove-mark.js b/packages/slate/test/models/text/marks/remove-mark/remove-mark.js
index f88f14ba6..334c27961 100644
--- a/packages/slate/test/models/text/marks/remove-mark/remove-mark.js
+++ b/packages/slate/test/models/text/marks/remove-mark/remove-mark.js
@@ -7,7 +7,7 @@ export const input = (
Cat is Cute
-)[0]
+)
export default function(t) {
return t.removeMark(0, 3, Mark.create('bold'))
@@ -17,4 +17,4 @@ export const output = (
Cat is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/update-mark/marked-text-with-some-other-makrs.js b/packages/slate/test/models/text/marks/update-mark/marked-text-with-some-other-makrs.js
index 0470524ba..4d6ab4c03 100644
--- a/packages/slate/test/models/text/marks/update-mark/marked-text-with-some-other-makrs.js
+++ b/packages/slate/test/models/text/marks/update-mark/marked-text-with-some-other-makrs.js
@@ -8,7 +8,7 @@ export const input = (
Cat
is Cute
-)[0]
+)
export default function(t) {
return t.updateMark(0, 6, Mark.create('bold'), { data: { x: 1 } })
@@ -19,4 +19,4 @@ export const output = (
Cat
is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/update-mark/marked-text.js b/packages/slate/test/models/text/marks/update-mark/marked-text.js
index ceff74260..c772dbe12 100644
--- a/packages/slate/test/models/text/marks/update-mark/marked-text.js
+++ b/packages/slate/test/models/text/marks/update-mark/marked-text.js
@@ -3,7 +3,11 @@
import { Mark } from 'slate'
import h from '../../../../helpers/h'
-export const input = Cat is Cute [0]
+export const input = (
+
+ Cat is Cute
+
+)
export default function(t) {
return t.updateMark(0, 3, Mark.create('bold'), { data: { x: 1 } })
@@ -14,4 +18,4 @@ export const output = (
Cat
is Cute
-)[0]
+)
diff --git a/packages/slate/test/models/text/marks/update-mark/null-mark-with-invalid-offset.js b/packages/slate/test/models/text/marks/update-mark/null-mark-with-invalid-offset.js
index 73775a029..15d1a2d44 100644
--- a/packages/slate/test/models/text/marks/update-mark/null-mark-with-invalid-offset.js
+++ b/packages/slate/test/models/text/marks/update-mark/null-mark-with-invalid-offset.js
@@ -3,7 +3,11 @@
import { Mark } from 'slate'
import h from '../../../../helpers/h'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.updateMark(0, 1, Mark.create('bold'), { data: { x: 1 } })
diff --git a/packages/slate/test/models/text/marks/update-mark/null-marked-text.js b/packages/slate/test/models/text/marks/update-mark/null-marked-text.js
index 294f4c2e1..3efb2fc8a 100644
--- a/packages/slate/test/models/text/marks/update-mark/null-marked-text.js
+++ b/packages/slate/test/models/text/marks/update-mark/null-marked-text.js
@@ -3,10 +3,18 @@
import { Mark } from 'slate'
import h from '../../../../helpers/h'
-export const input = [0]
+export const input = (
+
+
+
+)
export default function(t) {
return t.updateMark(0, 0, Mark.create('bold'), { data: { x: 1 } })
}
-export const output = [0]
+export const output = (
+
+
+
+)
diff --git a/packages/slate/test/models/text/merge/empty-leaf-as-next/length-text.js b/packages/slate/test/models/text/merge/empty-leaf-as-next/length-text.js
index 2c659cace..8e52a6edc 100644
--- a/packages/slate/test/models/text/merge/empty-leaf-as-next/length-text.js
+++ b/packages/slate/test/models/text/merge/empty-leaf-as-next/length-text.js
@@ -2,10 +2,21 @@
import h from '../../../../helpers/h'
-export const input = [Some [0], [0]]
-
-export default function(texts) {
- return texts[0].mergeText(texts[1])
+export const input = {
+ a: (
+
+ Some
+
+ ),
+ b: ,
}
-export const output = Some [0]
+export default function({ a, b }) {
+ return a.mergeText(b)
+}
+
+export const output = (
+
+ Some
+
+)
diff --git a/packages/slate/test/models/text/merge/empty-leaf-as-start/another-empty-text.js b/packages/slate/test/models/text/merge/empty-leaf-as-start/another-empty-text.js
index 78f59da23..d1181aaa0 100644
--- a/packages/slate/test/models/text/merge/empty-leaf-as-start/another-empty-text.js
+++ b/packages/slate/test/models/text/merge/empty-leaf-as-start/another-empty-text.js
@@ -2,10 +2,21 @@
import h from '../../../../helpers/h'
-export const input = [ [0], [0]]
-
-export default function(texts) {
- return texts[0].mergeText(texts[1])
+export const input = {
+ a: (
+
+
+
+ ),
+ b: ,
}
-export const output = [0]
+export default function({ a, b }) {
+ return a.mergeText(b)
+}
+
+export const output = (
+
+
+
+)
diff --git a/packages/slate/test/models/text/merge/empty-leaf-as-start/length-text.js b/packages/slate/test/models/text/merge/empty-leaf-as-start/length-text.js
index 4e8a6af14..12758c96d 100644
--- a/packages/slate/test/models/text/merge/empty-leaf-as-start/length-text.js
+++ b/packages/slate/test/models/text/merge/empty-leaf-as-start/length-text.js
@@ -2,10 +2,17 @@
import h from '../../../../helpers/h'
-export const input = [ [0], Some [0]]
-
-export default function(texts) {
- return texts[0].mergeText(texts[1])
+export const input = {
+ a: (
+
+
+
+ ),
+ b: Some ,
}
-export const output = Some [0]
+export default function({ a, b }) {
+ return a.mergeText(b)
+}
+
+export const output = Some
diff --git a/packages/slate/test/operations/apply/update-decorations/insert-text-before.js b/packages/slate/test/operations/apply/insert-text/decoration-before.js
similarity index 71%
rename from packages/slate/test/operations/apply/update-decorations/insert-text-before.js
rename to packages/slate/test/operations/apply/insert-text/decoration-before.js
index 68ebe34b5..45a464d0a 100644
--- a/packages/slate/test/operations/apply/update-decorations/insert-text-before.js
+++ b/packages/slate/test/operations/apply/insert-text/decoration-before.js
@@ -6,8 +6,8 @@ export default [
{
type: 'insert_text',
path: [0, 0],
- offset: 2,
- text: ' added',
+ offset: 1,
+ text: 'x',
marks: [],
},
]
@@ -16,7 +16,8 @@ export const input = (
- Hi there you
+ w
+ or d
@@ -26,7 +27,8 @@ export const output = (
- Hi added there you
+ wx
+ or d
diff --git a/packages/slate/test/operations/apply/update-decorations/merge-node.js b/packages/slate/test/operations/apply/merge-node/decoration-across-blocks.js
similarity index 63%
rename from packages/slate/test/operations/apply/update-decorations/merge-node.js
rename to packages/slate/test/operations/apply/merge-node/decoration-across-blocks.js
index bf5c39dda..ec132ec27 100644
--- a/packages/slate/test/operations/apply/update-decorations/merge-node.js
+++ b/packages/slate/test/operations/apply/merge-node/decoration-across-blocks.js
@@ -10,7 +10,6 @@ export default [
properties: {},
target: null,
},
- // also merge the resulting leaves
{
type: 'merge_node',
path: [0, 1],
@@ -24,10 +23,10 @@ export const input = (
- The decoration begins in this paragraph
+ o ne
- And ends in this soon-to-be merged one.
+ tw o
@@ -37,8 +36,7 @@ export const output = (
- The decoration begins in this paragraphAnd ends in
- this soon-to-be merged one.
+ onetw o
diff --git a/packages/slate/test/operations/apply/update-decorations/remove-node.js b/packages/slate/test/operations/apply/remove-node/decoration-across-blocks.js
similarity index 64%
rename from packages/slate/test/operations/apply/update-decorations/remove-node.js
rename to packages/slate/test/operations/apply/remove-node/decoration-across-blocks.js
index a6244e526..afaa86306 100644
--- a/packages/slate/test/operations/apply/update-decorations/remove-node.js
+++ b/packages/slate/test/operations/apply/remove-node/decoration-across-blocks.js
@@ -13,11 +13,10 @@ export const input = (
- The decoration begins in this soon deleted
- paragraph
+ o ne
- And ends in this one.
+ tw o
@@ -27,7 +26,7 @@ export const output = (
- And ends in this one.
+ tw o
diff --git a/packages/slate/test/operations/apply/remove-text/decoration-atomic-middle.js b/packages/slate/test/operations/apply/remove-text/decoration-atomic-middle.js
deleted file mode 100644
index e4c538a31..000000000
--- a/packages/slate/test/operations/apply/remove-text/decoration-atomic-middle.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-export default [
- {
- type: 'remove_text',
- path: [0, 0],
- offset: 1,
- text: 'o',
- marks: [],
- },
-]
-
-export const input = (
-
-
-
- wor d
-
-
-
-)
-
-export const output = (
-
-
- wrd
-
-
-)
diff --git a/packages/slate/test/schema/core/block-all-block-children.js b/packages/slate/test/schema/core/block-all-block-children.js
index 97b415004..9db43e104 100644
--- a/packages/slate/test/schema/core/block-all-block-children.js
+++ b/packages/slate/test/schema/core/block-all-block-children.js
@@ -15,36 +15,12 @@ export const input = (
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'quote',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'one',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+ one
+
+
+
+)
diff --git a/packages/slate/test/schema/core/block-all-inline-children.js b/packages/slate/test/schema/core/block-all-inline-children.js
index 20c6e7e74..0790c24cf 100644
--- a/packages/slate/test/schema/core/block-all-inline-children.js
+++ b/packages/slate/test/schema/core/block-all-inline-children.js
@@ -8,63 +8,23 @@ export const input = (
+
one
+
two
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'quote',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'one',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+
+ one
+
+
+
+
+)
diff --git a/packages/slate/test/schema/core/block-all-text-children.js b/packages/slate/test/schema/core/block-all-text-children.js
index e8e67b074..50c9d933d 100644
--- a/packages/slate/test/schema/core/block-all-text-children.js
+++ b/packages/slate/test/schema/core/block-all-text-children.js
@@ -15,29 +15,10 @@ export const input = (
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'quote',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'one',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+ one
+
+
+)
diff --git a/packages/slate/test/schema/core/block-create-text.js b/packages/slate/test/schema/core/block-create-text.js
index e98ea1670..c5bf7ae09 100644
--- a/packages/slate/test/schema/core/block-create-text.js
+++ b/packages/slate/test/schema/core/block-create-text.js
@@ -12,29 +12,12 @@ export const input = (
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+
+
+
+
+)
diff --git a/packages/slate/test/schema/core/document-no-inline-children.js b/packages/slate/test/schema/core/document-no-inline-children.js
index ae79220ae..0e0089e5d 100644
--- a/packages/slate/test/schema/core/document-no-inline-children.js
+++ b/packages/slate/test/schema/core/document-no-inline-children.js
@@ -13,29 +13,10 @@ export const input = (
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'two',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+ two
+
+
+)
diff --git a/packages/slate/test/schema/core/document-no-text-children.js b/packages/slate/test/schema/core/document-no-text-children.js
index 5caf95f72..119cf2299 100644
--- a/packages/slate/test/schema/core/document-no-text-children.js
+++ b/packages/slate/test/schema/core/document-no-text-children.js
@@ -13,29 +13,10 @@ export const input = (
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'two',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+ two
+
+
+)
diff --git a/packages/slate/test/schema/core/inline-no-block-children.js b/packages/slate/test/schema/core/inline-no-block-children.js
index 33ef2bd3f..fc4ffb2f0 100644
--- a/packages/slate/test/schema/core/inline-no-block-children.js
+++ b/packages/slate/test/schema/core/inline-no-block-children.js
@@ -8,65 +8,25 @@ export const input = (
-
+
+
one
two
+
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'two',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+
+ two
+
+
+
+
+)
diff --git a/packages/slate/test/schema/core/inline-text-around.js b/packages/slate/test/schema/core/inline-text-around.js
index 506d4fb14..0c0923d90 100644
--- a/packages/slate/test/schema/core/inline-text-around.js
+++ b/packages/slate/test/schema/core/inline-text-around.js
@@ -8,119 +8,23 @@ export const input = (
-
- one
- two
-
+ one
+ two
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'one',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'two',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+
+ one
+
+ two
+
+
+
+
+)
diff --git a/packages/slate/test/schema/core/merge-adjacent-texts-max-iterations.js b/packages/slate/test/schema/core/merge-adjacent-texts-max-iterations.js
deleted file mode 100644
index 8fdb58b16..000000000
--- a/packages/slate/test/schema/core/merge-adjacent-texts-max-iterations.js
+++ /dev/null
@@ -1,53 +0,0 @@
-export const schema = {}
-
-export const input = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: Array.from({ length: 100 }).map(() => ({
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'a',
- marks: [],
- },
- ],
- })),
- },
- ],
- },
-}
-
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'a'.repeat(100),
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
diff --git a/packages/slate/test/schema/core/merge-adjacent-texts.js b/packages/slate/test/schema/core/merge-adjacent-texts.js
index e11221fd9..1b7b42ffb 100644
--- a/packages/slate/test/schema/core/merge-adjacent-texts.js
+++ b/packages/slate/test/schema/core/merge-adjacent-texts.js
@@ -8,37 +8,26 @@ export const input = (
- one
- two
- three
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'onetwothree',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+ 123456789
+
+
+
+)
diff --git a/packages/slate/test/schema/core/preserve-inline-with-empty-void.js b/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
index 2657e5e31..95b520c8b 100644
--- a/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
+++ b/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
@@ -8,91 +8,34 @@ export const input = (
+
-
+
+
+
+
+
+
)
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: '',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
+export const output = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
diff --git a/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js b/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
index 7013521ce..2d5071f56 100644
--- a/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
+++ b/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
@@ -17,8 +17,10 @@ export const schema = {
min: 1,
},
],
- normalize: (change, { code, child }) => {
- if (code == 'child_object_invalid') {
+ normalize: (change, error) => {
+ const { code, child } = error
+
+ if (code === 'child_object_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/child-kind-invalid-default.js b/packages/slate/test/schema/custom/child-kind-invalid-default.js
index 8c0848241..0cde78f2f 100644
--- a/packages/slate/test/schema/custom/child-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/child-kind-invalid-default.js
@@ -28,7 +28,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/child-kind-invalid-function.js b/packages/slate/test/schema/custom/child-kind-invalid-function.js
index bc7270ecd..ee2ba7659 100644
--- a/packages/slate/test/schema/custom/child-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/child-kind-invalid-function.js
@@ -28,7 +28,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/child-required-custom.js b/packages/slate/test/schema/custom/child-required-custom.js
index 26f45b579..24ae25ea7 100644
--- a/packages/slate/test/schema/custom/child-required-custom.js
+++ b/packages/slate/test/schema/custom/child-required-custom.js
@@ -28,7 +28,9 @@ export const input = (
-
+
+
+
@@ -38,8 +40,12 @@ export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/child-required-default.js b/packages/slate/test/schema/custom/child-required-default.js
index 08bcd3a99..d381b1ad8 100644
--- a/packages/slate/test/schema/custom/child-required-default.js
+++ b/packages/slate/test/schema/custom/child-required-default.js
@@ -19,7 +19,9 @@ export const schema = {
export const input = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/child-type-invalid-custom.js b/packages/slate/test/schema/custom/child-type-invalid-custom.js
index 22b169168..d8a204d4b 100644
--- a/packages/slate/test/schema/custom/child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/child-type-invalid-custom.js
@@ -24,7 +24,9 @@ export const input = (
-
+
+
+
@@ -35,7 +37,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/child-type-invalid-default.js b/packages/slate/test/schema/custom/child-type-invalid-default.js
index b91af43d2..0f9271380 100644
--- a/packages/slate/test/schema/custom/child-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/child-type-invalid-default.js
@@ -19,7 +19,9 @@ export const input = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/child-type-invalid-function.js b/packages/slate/test/schema/custom/child-type-invalid-function.js
index 96819ae64..95d86943e 100644
--- a/packages/slate/test/schema/custom/child-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/child-type-invalid-function.js
@@ -19,7 +19,9 @@ export const input = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/first-child-kind-invalid-default.js b/packages/slate/test/schema/custom/first-child-kind-invalid-default.js
index 464603876..e408a4816 100644
--- a/packages/slate/test/schema/custom/first-child-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/first-child-kind-invalid-default.js
@@ -15,7 +15,9 @@ export const input = (
-
+
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/first-child-kind-invalid-function.js b/packages/slate/test/schema/custom/first-child-kind-invalid-function.js
index 2ccaddc04..8faa28708 100644
--- a/packages/slate/test/schema/custom/first-child-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/first-child-kind-invalid-function.js
@@ -15,7 +15,9 @@ export const input = (
-
+
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/first-child-type-invalid-custom.js b/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
index 9156f2e19..40bd49406 100644
--- a/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
@@ -20,9 +20,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -33,10 +39,16 @@ export const output = (
-
+
+
+
+
+
+
+
+
+
-
-
diff --git a/packages/slate/test/schema/custom/first-child-type-invalid-default.js b/packages/slate/test/schema/custom/first-child-type-invalid-default.js
index 188d0a94a..020ee374c 100644
--- a/packages/slate/test/schema/custom/first-child-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/first-child-type-invalid-default.js
@@ -15,9 +15,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -27,8 +33,12 @@ export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/first-child-type-invalid-function.js b/packages/slate/test/schema/custom/first-child-type-invalid-function.js
index 884b6a56c..b6c57e25e 100644
--- a/packages/slate/test/schema/custom/first-child-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/first-child-type-invalid-function.js
@@ -15,9 +15,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -27,8 +33,12 @@ export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/last-child-kind-invalid-default.js b/packages/slate/test/schema/custom/last-child-kind-invalid-default.js
index 038fad0ec..1955d073e 100644
--- a/packages/slate/test/schema/custom/last-child-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/last-child-kind-invalid-default.js
@@ -15,7 +15,9 @@ export const input = (
-
+
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/last-child-kind-invalid-function.js b/packages/slate/test/schema/custom/last-child-kind-invalid-function.js
index 4439cec0b..e8a7e1356 100644
--- a/packages/slate/test/schema/custom/last-child-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/last-child-kind-invalid-function.js
@@ -15,7 +15,9 @@ export const input = (
-
+
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/last-child-type-invalid-custom.js b/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
index bf5de7aec..7474a1398 100644
--- a/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
@@ -20,9 +20,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -32,10 +38,16 @@ export const output = (
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/last-child-type-invalid-default.js b/packages/slate/test/schema/custom/last-child-type-invalid-default.js
index 5310cfdab..8d33499fe 100644
--- a/packages/slate/test/schema/custom/last-child-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/last-child-type-invalid-default.js
@@ -15,9 +15,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -27,8 +33,12 @@ export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/last-child-type-invalid-function.js b/packages/slate/test/schema/custom/last-child-type-invalid-function.js
index fe74d438c..1e4880933 100644
--- a/packages/slate/test/schema/custom/last-child-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/last-child-type-invalid-function.js
@@ -15,9 +15,15 @@ export const input = (
-
-
-
+
+
+
+
+
+
+
+
+
@@ -27,8 +33,12 @@ export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/match-data.js b/packages/slate/test/schema/custom/match-data.js
index dcd2fe184..f1149a6f8 100644
--- a/packages/slate/test/schema/custom/match-data.js
+++ b/packages/slate/test/schema/custom/match-data.js
@@ -14,7 +14,9 @@ export const schema = {
export const input = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/match-object.js b/packages/slate/test/schema/custom/match-object.js
index 3a6c59161..f7eacf34b 100644
--- a/packages/slate/test/schema/custom/match-object.js
+++ b/packages/slate/test/schema/custom/match-object.js
@@ -16,7 +16,9 @@ export const schema = {
export const input = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/next-kind-invalid-custom.js b/packages/slate/test/schema/custom/next-kind-invalid-custom.js
index 3fced31c4..96e8efa0c 100644
--- a/packages/slate/test/schema/custom/next-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/next-kind-invalid-custom.js
@@ -19,8 +19,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -30,9 +34,13 @@ export const output = (
-
+
+
+
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/next-kind-invalid-default.js b/packages/slate/test/schema/custom/next-kind-invalid-default.js
index 952c18b41..df5f62b6b 100644
--- a/packages/slate/test/schema/custom/next-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/next-kind-invalid-default.js
@@ -14,8 +14,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -25,7 +29,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/next-kind-invalid-function.js b/packages/slate/test/schema/custom/next-kind-invalid-function.js
index 5d8d56e4c..f865aac52 100644
--- a/packages/slate/test/schema/custom/next-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/next-kind-invalid-function.js
@@ -14,8 +14,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -25,7 +29,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/next-type-invalid-custom.js b/packages/slate/test/schema/custom/next-type-invalid-custom.js
index da3f8a397..bed770c40 100644
--- a/packages/slate/test/schema/custom/next-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/next-type-invalid-custom.js
@@ -18,8 +18,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -27,9 +31,13 @@ export const input = (
export const output = (
-
-
+
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/next-type-invalid-default.js b/packages/slate/test/schema/custom/next-type-invalid-default.js
index d57f86ca0..4f34ce7b0 100644
--- a/packages/slate/test/schema/custom/next-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/next-type-invalid-default.js
@@ -13,8 +13,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -22,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/next-type-invalid-function.js b/packages/slate/test/schema/custom/next-type-invalid-function.js
index 9d3f40cc0..da4af3b42 100644
--- a/packages/slate/test/schema/custom/next-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/next-type-invalid-function.js
@@ -13,8 +13,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -22,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-data-invalid-custom.js b/packages/slate/test/schema/custom/node-data-invalid-custom.js
index 605ce1a70..5e2b7560b 100644
--- a/packages/slate/test/schema/custom/node-data-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-data-invalid-custom.js
@@ -20,7 +20,9 @@ export const schema = {
export const input = (
-
+
+
+
)
@@ -28,7 +30,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-data-invalid-default-undefined.js b/packages/slate/test/schema/custom/node-data-invalid-default-undefined.js
index 406e0c9b7..027792d0f 100644
--- a/packages/slate/test/schema/custom/node-data-invalid-default-undefined.js
+++ b/packages/slate/test/schema/custom/node-data-invalid-default-undefined.js
@@ -15,7 +15,9 @@ export const schema = {
export const input = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-data-invalid-default.js b/packages/slate/test/schema/custom/node-data-invalid-default.js
index 03fcab0a9..2c19a1a69 100644
--- a/packages/slate/test/schema/custom/node-data-invalid-default.js
+++ b/packages/slate/test/schema/custom/node-data-invalid-default.js
@@ -15,7 +15,9 @@ export const schema = {
export const input = (
-
+
+
+
)
@@ -23,7 +25,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-data-invalid-function.js b/packages/slate/test/schema/custom/node-data-invalid-function.js
index 1de89bcef..5ea66f98d 100644
--- a/packages/slate/test/schema/custom/node-data-invalid-function.js
+++ b/packages/slate/test/schema/custom/node-data-invalid-function.js
@@ -13,8 +13,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -22,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-mark-invalid-custom.js b/packages/slate/test/schema/custom/node-mark-invalid-custom.js
index 0951c8eea..a8fd5047e 100644
--- a/packages/slate/test/schema/custom/node-mark-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-mark-invalid-custom.js
@@ -28,7 +28,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/node-text-invalid-custom.js b/packages/slate/test/schema/custom/node-text-invalid-custom.js
index e3ac1ffbd..8874b70db 100644
--- a/packages/slate/test/schema/custom/node-text-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-text-invalid-custom.js
@@ -26,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/parent-kind-invalid-default.js b/packages/slate/test/schema/custom/parent-kind-invalid-default.js
index 146d5799d..7680be5d9 100644
--- a/packages/slate/test/schema/custom/parent-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/parent-kind-invalid-default.js
@@ -14,9 +14,13 @@ export const input = (
+
+
one
+
+
@@ -26,7 +30,11 @@ export const output = (
-
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/parent-kind-invalid-function.js b/packages/slate/test/schema/custom/parent-kind-invalid-function.js
index 91974a364..5df115e55 100644
--- a/packages/slate/test/schema/custom/parent-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/parent-kind-invalid-function.js
@@ -14,9 +14,13 @@ export const input = (
+
+
one
+
+
@@ -26,7 +30,11 @@ export const output = (
-
+
+
+
+
+
diff --git a/packages/slate/test/schema/custom/parent-type-invalid-custom.js b/packages/slate/test/schema/custom/parent-type-invalid-custom.js
index 9f1e88bf4..aa3376f01 100644
--- a/packages/slate/test/schema/custom/parent-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/parent-type-invalid-custom.js
@@ -20,7 +20,9 @@ export const input = (
-
+ -
+
+
@@ -31,7 +33,9 @@ export const output = (
-
+ -
+
+
diff --git a/packages/slate/test/schema/custom/parent-type-invalid-default.js b/packages/slate/test/schema/custom/parent-type-invalid-default.js
index b382e2946..6fb9d7d97 100644
--- a/packages/slate/test/schema/custom/parent-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/parent-type-invalid-default.js
@@ -15,7 +15,9 @@ export const input = (
-
+ -
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/parent-type-invalid-function.js b/packages/slate/test/schema/custom/parent-type-invalid-function.js
index f37dcb00f..1f2910896 100644
--- a/packages/slate/test/schema/custom/parent-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/parent-type-invalid-function.js
@@ -15,7 +15,9 @@ export const input = (
-
+ -
+
+
@@ -24,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/previous-kind-invalid-custom.js b/packages/slate/test/schema/custom/previous-kind-invalid-custom.js
index 51806aecc..55ed0426a 100644
--- a/packages/slate/test/schema/custom/previous-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/previous-kind-invalid-custom.js
@@ -19,8 +19,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -29,9 +33,13 @@ export const input = (
export const output = (
-
+
+
+
-
+
+
+
diff --git a/packages/slate/test/schema/custom/previous-kind-invalid-default.js b/packages/slate/test/schema/custom/previous-kind-invalid-default.js
index 9b89a6590..9857039a4 100644
--- a/packages/slate/test/schema/custom/previous-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/previous-kind-invalid-default.js
@@ -14,8 +14,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -25,7 +29,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/previous-kind-invalid-function.js b/packages/slate/test/schema/custom/previous-kind-invalid-function.js
index 6a17ea716..b5101a240 100644
--- a/packages/slate/test/schema/custom/previous-kind-invalid-function.js
+++ b/packages/slate/test/schema/custom/previous-kind-invalid-function.js
@@ -14,8 +14,12 @@ export const input = (
-
-
+
+
+
+
+
+
@@ -25,7 +29,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/schema/custom/previous-type-invalid-custom.js b/packages/slate/test/schema/custom/previous-type-invalid-custom.js
index 1d0187030..8db09550e 100644
--- a/packages/slate/test/schema/custom/previous-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/previous-type-invalid-custom.js
@@ -6,8 +6,10 @@ export const schema = {
blocks: {
paragraph: {
previous: [{ type: 'paragraph' }],
- normalize: (change, { code, previous }) => {
- if (code == 'previous_sibling_type_invalid') {
+ normalize: (change, error) => {
+ const { code, previous } = error
+
+ if (code === 'previous_sibling_type_invalid') {
change.wrapBlockByKey(previous.key, 'paragraph')
}
},
@@ -18,8 +20,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -28,9 +34,13 @@ export const output = (
-
+
+
+
+
+
+
-
)
diff --git a/packages/slate/test/schema/custom/previous-type-invalid-default.js b/packages/slate/test/schema/custom/previous-type-invalid-default.js
index 0e40604dd..dd1e48fbc 100644
--- a/packages/slate/test/schema/custom/previous-type-invalid-default.js
+++ b/packages/slate/test/schema/custom/previous-type-invalid-default.js
@@ -13,8 +13,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -22,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/previous-type-invalid-function.js b/packages/slate/test/schema/custom/previous-type-invalid-function.js
index dfa813401..b4b5c974b 100644
--- a/packages/slate/test/schema/custom/previous-type-invalid-function.js
+++ b/packages/slate/test/schema/custom/previous-type-invalid-function.js
@@ -13,8 +13,12 @@ export const schema = {
export const input = (
-
-
+
+
+
+
+
+
)
@@ -22,7 +26,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js b/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js
deleted file mode 100644
index f92c63149..000000000
--- a/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-export const input = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'image',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
-
-export const output = (
-
-
-
-
-
-)
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-nested.js b/packages/slate/test/serializers/raw/deserialize/inline-nested.js
index d4a0cbbcf..38ddfd951 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline-nested.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline-nested.js
@@ -87,9 +87,13 @@ export const output = (
+
+
one
+
+
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-with-data.js b/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
index 74efe6b3b..702a59383 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
@@ -62,7 +62,9 @@ export const output = (
+
one
+
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js b/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js
deleted file mode 100644
index 7322a2ae7..000000000
--- a/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-export const input = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'emoji',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
-
-export const output = (
-
-
-
-
-
-
-
-)
diff --git a/packages/slate/test/serializers/raw/deserialize/inline.js b/packages/slate/test/serializers/raw/deserialize/inline.js
index 5492f9f5f..8fd05b2fa 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline.js
@@ -60,7 +60,9 @@ export const output = (
+
one
+
diff --git a/packages/slate/test/serializers/raw/serialize/block-with-is-void.js b/packages/slate/test/serializers/raw/serialize/block-with-is-void.js
deleted file mode 100644
index acbfb7793..000000000
--- a/packages/slate/test/serializers/raw/serialize/block-with-is-void.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-export const input = (
-
-
-
-
-
-)
-
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'image',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
diff --git a/packages/slate/test/serializers/raw/serialize/inline-nested.js b/packages/slate/test/serializers/raw/serialize/inline-nested.js
index 966b1b555..3ee95f474 100644
--- a/packages/slate/test/serializers/raw/serialize/inline-nested.js
+++ b/packages/slate/test/serializers/raw/serialize/inline-nested.js
@@ -6,9 +6,13 @@ export const input = (
+
+
one
+
+
diff --git a/packages/slate/test/serializers/raw/serialize/inline-with-data.js b/packages/slate/test/serializers/raw/serialize/inline-with-data.js
index 67e89ad62..ca32874d4 100644
--- a/packages/slate/test/serializers/raw/serialize/inline-with-data.js
+++ b/packages/slate/test/serializers/raw/serialize/inline-with-data.js
@@ -6,7 +6,9 @@ export const input = (
+
one
+
diff --git a/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js b/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js
deleted file mode 100644
index 141862835..000000000
--- a/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-export const input = (
-
-
-
-
-
-
-
-)
-
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'emoji',
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
diff --git a/packages/slate/test/serializers/raw/serialize/inline.js b/packages/slate/test/serializers/raw/serialize/inline.js
index 0d67794c3..6855dae86 100644
--- a/packages/slate/test/serializers/raw/serialize/inline.js
+++ b/packages/slate/test/serializers/raw/serialize/inline.js
@@ -6,7 +6,9 @@ export const input = (
+
one
+
diff --git a/support/rollup/config.js b/support/rollup/config.js
index 585f62754..6ea216cdc 100644
--- a/support/rollup/config.js
+++ b/support/rollup/config.js
@@ -2,27 +2,23 @@ import factory from './factory'
import slate from '../../packages/slate/package.json'
import slateBase64Serializer from '../../packages/slate-base64-serializer/package.json'
import slateDevEnvironment from '../../packages/slate-dev-environment/package.json'
-import slateDevWarning from '../../packages/slate-dev-warning/package.json'
import slateHotkeys from '../../packages/slate-hotkeys/package.json'
import slateHtmlSerializer from '../../packages/slate-html-serializer/package.json'
import slateHyperscript from '../../packages/slate-hyperscript/package.json'
import slatePlainSerializer from '../../packages/slate-plain-serializer/package.json'
import slatePropTypes from '../../packages/slate-prop-types/package.json'
import slateReact from '../../packages/slate-react/package.json'
-import slateSimulator from '../../packages/slate-simulator/package.json'
const configurations = [
...factory(slate),
...factory(slateBase64Serializer),
...factory(slateDevEnvironment),
- ...factory(slateDevWarning),
...factory(slateHotkeys),
...factory(slateHtmlSerializer),
...factory(slateHyperscript),
...factory(slatePlainSerializer),
...factory(slatePropTypes),
...factory(slateReact),
- ...factory(slateSimulator),
]
export default configurations
diff --git a/yarn.lock b/yarn.lock
index 428d95689..413ce88e9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7445,6 +7445,10 @@ slate-collapse-on-escape@^0.6.0:
dependencies:
to-pascal-case "^1.0.0"
+slate-simulator@^0.4.67:
+ version "0.4.67"
+ resolved "https://registry.yarnpkg.com/slate-simulator/-/slate-simulator-0.4.67.tgz#9313c84736db1e23d6aebacd536f582b6d54723c"
+
slate-soft-break@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/slate-soft-break/-/slate-soft-break-0.6.0.tgz#1e44815b7ff4ddada055bba14cd0d2d4ef0fd463"
@@ -8029,6 +8033,14 @@ tiny-emitter@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-1.2.0.tgz#6dc845052cb08ebefc1874723b58f24a648c3b6f"
+tiny-invariant@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.1.tgz#54700d039a0384ef2e83afd0e81af84c6d67b140"
+
+tiny-warning@^0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-0.0.3.tgz#1807eb4c5f81784a6354d58ea1d5024f18c6c81f"
+
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"