Change
import { Change } from 'slate'A change allows you to define a series of changes you'd like to make to the current Value.
All changes are performed through Change objects, so that a history of changes can be preserved for use in undo/redo operations, and to make collaborative editing possible.
Properties
object
objectString
A string with a value of 'change'.
value
valueA Value with the change's current operations applied. Each time you run a new change function this property will be updated.
Methods
call
callcall(fn: Function, ...args) => Change
This method calls the provided function with the current instance of the Change object as the first argument and passes through the remaining args.
The purpose of call is to enable custom change methods to exist and called in a chain. For example:
function addBoldMark(change) {
change.addMark('bold_mark')
}
function insertParagraph(change) {
change.insertBlock('paragraph_block')
}
function onSomeEvent(event, change) {
change
.call(insertParagraph)
.insertText('Some text...')
.extendToStartOfBlock()
.call(addBoldMark)
.collapseToEnd()
}normalize
normalizenormalize() => Void
This method normalizes the document with the value's schema. This should run automatically-you should not need to call this method unless you have manually disabled normalization (and you should rarely, if ever, need to manually disable normalization). The vast majority of changes, whether by the user or invoked programmatically, will run normalize by default to ensure the document is always in adherence to its schema.
🤖 If you must use this method, use it sparingly and strategically. Calling this method can be very expensive as it will run normalization on all of the nodes in your document.
withoutNormalizing
withoutNormalizingwithoutNormalizing(fn: Function) => Change
This method calls the provided function with the current instance of the Change object as the first argument. Normalization does not occur while the fuction is executing, and is instead deferred to be be run immediately after it completes.
This method can be used to allow a sequence of change operations that should not be interrupted by normalization. For example:
function removeManyNodes(node) {
const toRemove = node.nodes.filter(n => n.object != 'block')
if (!toRemove.size) return
change.withoutNormalizing(() => {
toRemove.forEach(child => {
change.removeNodeByKey(child.key)
})
})
}withoutSaving
withoutSavingwithoutSaving(fn: Function) => Change
By default all new operations are saved to the editor's history. If you have changes that you don't want to show up in the history when the user presses cmd+z, you can use withoutSaving to skip those changes.
change.withoutSaving(() => {
change.setValue({ decorations })
})However, be sure you know what you are doing because this will create changes that cannot be undone by the user, and might result in confusing behaviors.
withoutMerging
withoutMergingwithoutMerging(fn: Function) => Change
Usually, all of the operations in a Change are grouped into a single save point in the editor's history. However, sometimes you may want more control over this, to be able to create distinct save points in a single change. To do that, you can use the withoutMerging helper.
Full Value Change
setValue
setValuesetValue(properties: Object, [options: Object]) => Change
setValue(value: Value, [options: Object]) => Change (see warning below)
Set the entire value using either a properties object or a Value object. Can be used to set value.data and other properties that cannot otherwise be easily set using the available methods.
Current Selection Changes
These changes act on the document based on the current selection. They are equivalent to calling the Document Range Changes with the current selection as the range argument, but they are there for convenience, since you often want to act with the current selection, as a user would.
addMark
addMarkaddMark(mark: Mark) => Change
addMark(properties: Object) => Change
addMark(type: String) => Change
Add a mark to the characters in the current selection. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
delete
deletedelete() => Change
Delete everything in the current selection.
insertBlock
insertBlockinsertBlock(block: Block) => Change
insertBlock(properties: Object) => Change
insertBlock(type: String) => Change
deleteBackward
deleteBackwarddeleteBackward(n: Number) => Change
Delete backward n characters at the current cursor. If the selection is expanded, this method is equivalent to a regular delete(). n defaults to 1.
deleteForward
deleteForwarddeleteForward(n: Number) => Change
Delete forward n characters at the current cursor. If the selection is expanded, this method is equivalent to a regular delete(). n defaults to 1.
Insert a new block at the same level as the current block, splitting the current block to make room if it is non-empty. If the selection is expanded, it will be deleted first.
insertFragment
insertFragmentinsertFragment(fragment: Document) => Change
Insert a fragment at the current selection. If the selection is expanded, it will be deleted first.
insertInline
insertInlineinsertInline(inline: Inline) => Change
insertInline(properties: Object) => Change
Insert a new inline at the current cursor position, splitting the text to make room if it is non-empty. If the selection is expanded, it will be deleted first.
insertText
insertTextinsertText(text: String) => Change
Insert a string of text at the current selection. If the selection is expanded, it will be deleted first.
setBlocks
setBlockssetBlocks(properties: Object) => Change
setBlocks(type: String) => Change
Set the properties of the Blocks in the current selection. For convenience, you can pass a type string to set the blocks' type only.
setInlines
setInlinessetInlines(properties: Object) => Change
setInlines(type: String) => Change
Set the properties of the Inlines nodes in the current selection. For convenience, you can pass a type string to set the inline nodes' type only.
splitBlock
splitBlocksplitBlock(depth: Number) => Change
Split the Block in the current selection by depth levels. If the selection is expanded, it will be deleted first. depth defaults to 1.
splitInline
splitInlinesplitInline(depth: Number) => Change
Split the Inline node in the current selection by depth levels. If the selection is expanded, it will be deleted first. depth defaults to Infinity.
removeMark
removeMarkremoveMark(mark: Mark) => Change
removeMark(properties: Object) => Change
removeMark(type: String) => Change
Remove a mark from the characters in the current selection. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
replaceMark
replaceMarkreplaceMark(oldMark: Mark, newMark: Mark) => Change
replaceMark(oldProperties: Object, newProperties: Object) => Change
replaceMark(oldType: String, newType: String) => Change
Replace a mark in the characters in the current selection. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
toggleMark
toggleMarktoggleMark(mark: Mark) => Change
toggleMark(properties: Object) => Change
toggleMark(type: String) => Change
Add or remove a mark from the characters in the current selection, depending on it already exists on any or not. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
unwrapBlock
unwrapBlockunwrapBlock(type: String) => Change
unwrapBlock(properties: Object) => Change
Unwrap all Block nodes in the current selection that match a type and/or data.
unwrapInline
unwrapInlineunwrapInline(type: String) => Change
unwrapInline(properties: Object) => Change
Unwrap all Inline nodes in the current selection that match a type and/or data.
wrapBlock
wrapBlockwrapBlock(type: String) => Change
wrapBlock(properties: Object) => Change
Wrap the Block nodes in the current selection with a new Block node of type, with optional data.
wrapInline
wrapInlinewrapInline(type: String) => Change
wrapInline(properties: Object) => Change
Wrap the Inline nodes in the current selection with a new Inline node of type, with optional data.
wrapText
wrapTextwrapText(prefix: String, [suffix: String]) => Change
Surround the text in the current selection with prefix and suffix strings. If the suffix is ommitted, the prefix will be used instead.
Selection Changes
These changes change the current selection, without touching the document.
blur
blurblur() => Change
Blur the current selection.
deselect
deselectdeselect() => Change
Unset the selection.
flip
flipflip() => Change
Flip the selection.
focus
focusfocus() => Change
Focus the current selection.
move{Point}Backward
move{Point}Backwardmove{Point}Backward(n: Number) => Change
Move the {Point} of the selection backward n characters. Where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}Forward
move{Point}Forwardmove{Point}Forward(n: Number) => Change
Move the {Point} of the selection forward n characters. Where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To
move{Point}TomoveTo(path: List, offset: Number) => Change moveTo(key: String, offset: Number) => Change moveTo(offset: Number) => Change
Move the {Point} of the selection to a new path or key and offset. Where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
moveTo{Point}
moveTo{Point}moveTo{Point}() => Change
Collapse the current selection to one of its points. Where {Point} is either Anchor, Focus, Start or End.
move{Point}To{Edge}OfBlock
move{Point}To{Edge}OfBlockmove{Point}To{Edge}OfBlock() => Change
Move the current selection to the {Edge} of the closest block parent. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}OfDocument
move{Point}To{Edge}OfDocumentmove{Point}To{Edge}OfDocument() => Change
Move the current selection to the {Edge} of the document. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}OfInline
move{Point}To{Edge}OfInlinemove{Point}To{Edge}OfInline() => Change
Move the current selection to the {Edge} of the closest inline parent. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}OfNode
move{Point}To{Edge}OfNodemove{Point}To{Edge}OfNode(node: Node) => Change
Move the current selection to the {Edge} of a node. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}OfText
move{Point}To{Edge}OfTextmove{Point}To{Edge}OfText() => Change
Move the current selection to the {Edge} of the current text node. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}Of{Direction}Block
move{Point}To{Edge}Of{Direction}Blockmove{Point}To{Edge}Of{Direction}Block() => Change
Move the current selection to the {Edge} of the closest block parent. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}Of{Direction}Inline
move{Point}To{Edge}Of{Direction}Inlinemove{Point}To{Edge}Of{Direction}Inline() => Change
Move the current selection to the {Edge} of the closest inline parent. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
move{Point}To{Edge}Of{Direction}Text
move{Point}To{Edge}Of{Direction}Textmove{Point}To{Edge}Of{Direction}Text() => Change
Move the current selection to the {Edge} of the current text node. Where {Edge} is either Start or End. And where {Point} is either Anchor, Focus, Start or End. You can also omit {Point} to move both the anchor and focus points at the same time.
moveToRangeOf
moveToRangeOfmoveToRangeOf(node: Node) => Change
Move the current selection's anchor point to the start of a node and its focus point to the end of the node.
moveToRangeOfDocument
moveToRangeOfDocumentmoveToRangeOf() => Change
Move the current selection's anchor point to the start of the document and its focus point to the end of the document, selecting everything.
select
selectselect(properties: Range || Object) => Change
Set the current selection to a range with merged properties. The properties can either be a Range object or a plain Javascript object of selection properties.
Document Range Changes
These changes act on a specific Range of the document.
addMarkAtRange
addMarkAtRangeaddMarkAtRange(range: Range, mark: Mark) => Change
addMarkAtRange(range: Range, properties: Object) => Change
addMarkAtRange(range: Range, type: String) => Change
Add a mark to the characters in a range. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
deleteAtRange
deleteAtRangedeleteAtRange(range: Range, ) => Change
Delete everything in a range.
deleteBackwardAtRange
deleteBackwardAtRangedeleteBackwardAtRange(range: Range, n: Number) => Change
Delete backward n characters at a range. If the range is expanded, this method is equivalent to a regular delete(). n defaults to 1.
deleteForwardAtRange
deleteForwardAtRangedeleteForwardAtRange(range: Range, n: Number) => Change
Delete forward n characters at a range. If the range is expanded, this method is equivalent to a regular delete(). n defaults to 1.
insertBlockAtRange
insertBlockAtRangeinsertBlockAtRange(range: Range, block: Block) => Change
insertBlockAtRange(range: Range, properties: Object) => Change
insertBlockAtRange(range: Range, type: String) => Change
Insert a new block at the same level as the leaf block at a range, splitting the current block to make room if it is non-empty. If the selection is expanded, it will be deleted first.
insertFragmentAtRange
insertFragmentAtRangeinsertFragmentAtRange(range: Range, fragment: Document) => Change
Insert a fragment at a range. If the selection is expanded, it will be deleted first.
insertInlineAtRange
insertInlineAtRangeinsertInlineAtRange(range: Range, inline: Inline) => Change
insertInlineAtRange(range: Range, properties: Object) => Change
Insert a new inline at a range, splitting the text to make room if it is non-empty. If the selection is expanded, it will be deleted first.
insertTextAtRange
insertTextAtRangeinsertTextAtRange(range: Range, text: String) => Change
Insert a string of text at a range. If the selection is expanded, it will be deleted first.
setBlocksAtRange
setBlocksAtRangesetBlocksAtRange(range: Range, properties: Object) => Change
setBlocks(range: Range, type: String) => Change
Set the properties of the Blocks in a range. For convenience, you can pass a type string to set the blocks' type only.
setInlinesAtRange
setInlinesAtRangesetInlinesAtRange(range: Range, properties: Object) => Change
setInlines(range: Range, type: String) => Change
Set the properties of the Inlines nodes in a range. For convenience, you can pass a type string to set the inline nodes' type only.
splitBlockAtRange
splitBlockAtRangesplitBlockAtRange(range: Range, depth: Number) => Change
Split the Block in a range by depth levels. If the selection is expanded, it will be deleted first. depth defaults to 1.
splitInlineAtRange
splitInlineAtRangesplitInlineAtRange(range: Range, depth: Number) => Change
Split the Inline node in a range by depth levels. If the selection is expanded, it will be deleted first. depth defaults to Infinity.
removeMarkAtRange
removeMarkAtRangeremoveMarkAtRange(range: Range, mark: Mark) => Change
removeMarkAtRange(range: Range, properties: Object) => Change
removeMarkAtRange(range: Range, type: String) => Change
Remove a mark from the characters in a range. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
toggleMarkAtRange
toggleMarkAtRangetoggleMarkAtRange(range: Range, mark: Mark) => Change
toggleMarkAtRange(range: Range, properties: Object) => Change
toggleMarkAtRange(range: Range, type: String) => Change
Add or remove a mark from the characters in a range, depending on whether any of them already have the mark. For convenience, you can pass a type string or properties object to implicitly create a Mark of that type.
unwrapBlockAtRange
unwrapBlockAtRangeunwrapBlockAtRange(range: Range, properties: Object) => Change
unwrapBlockAtRange(range: Range, type: String) => Change
Unwrap all Block nodes in a range that match properties. For convenience, you can pass a type string or properties object.
unwrapInlineAtRange
unwrapInlineAtRangeunwrapInlineAtRange(range: Range, properties: Object) => Change
unwrapInlineAtRange(range: Range, type: String) => Change
Unwrap all Inline nodes in a range that match properties. For convenience, you can pass a type string or properties object.
wrapBlockAtRange
wrapBlockAtRangewrapBlockAtRange(range: Range, properties: Object) => Change
wrapBlockAtRange(range: Range, type: String) => Change
Wrap the Block nodes in a range with a new Block node with properties. For convenience, you can pass a type string or properties object.
wrapInlineAtRange
wrapInlineAtRangewrapInlineAtRange(range: Range, properties: Object) => Change
wrapInlineAtRange(range: Range, type: String) => Change
Wrap the Inline nodes in a range with a new Inline node with properties. For convenience, you can pass a type string or properties object.
wrapTextAtRange
wrapTextAtRangewrapTextAtRange(range: Range, prefix: String, [suffix: String]) => Change
Surround the text in a range with prefix and suffix strings. If the suffix is ommitted, the prefix will be used instead.
Node Changes
These changes are lower-level, and act on a specific node by its key or path. They're often used in your custom components because you'll have access to props.node.
addMarkByKey/Path
addMarkByKey/PathaddMarkByKey(key: String, offset: Number, length: Number, mark: Mark) => Change addMarkByPath(path: List, offset: Number, length: Number, mark: Mark) => Change
Add a mark to length characters starting at an offset in a Node by its key or path.
insertNodeByKey/Path
insertNodeByKey/PathinsertNodeByKey(key: String, index: Number, node: Node) => Change insertNodeByPath(path: List, index: Number, node: Node) => Change
Insert a node at index inside a parent Node by its key or path.
insertFragmentByKey/Path
insertFragmentByKey/PathinsertFragmentByKey(key: String, index: Number, fragment: Fragment) => Transform insertFragmentByPath(path: list, index: Number, fragment: Fragment) => Transform
Insert a Fragment at index inside a parent Node by its key or path.
insertTextByKey/Path
insertTextByKey/PathinsertTextByKey(key: String, offset: Number, text: String, [marks: Set]) => Change insertTextByPath(path: List, offset: Number, text: String, [marks: Set]) => Change
Insert text at an offset in a Text Node by its key with optional marks.
mergeNodeByKey/Path
mergeNodeByKey/PathmergeNodeByKey(key: String) => Change mergeNodeByPath(path: List) => Change
Merge a Node by its key or path with its previous sibling.
moveNodeByKey/Path
moveNodeByKey/PathmoveNodeByKey(key: String, newKey: String, newIndex: Number) => Change moveNodeByPath(path: List, newKey: String, newIndex: Number) => Change
Move a Node by its key or path to a new parent node with its newKey and at a newIndex.
removeMarkByKey/Path
removeMarkByKey/PathremoveMarkByKey(key: String, offset: Number, length: Number, mark: Mark) => Change removeMarkByPath(path: List, offset: Number, length: Number, mark: Mark) => Change
Remove a mark from length characters starting at an offset in a Node by its key or path.
removeNodeByKey/Path
removeNodeByKey/PathremoveNodeByKey(key: String) => Change removeNodeByPath(path: List) => Change
Remove a Node from the document by its key or path.
replaceNodeByKey/Path
replaceNodeByKey/PathreplaceNodeByKey(key: String, node: Node) => Change replaceNodeByPath(path: List, node: Node) => Change
Replace a Node in the document with a new Node by its key or path.
removeTextByKey/Path
removeTextByKey/PathremoveTextByKey(key: String, offset: Number, length: Number) => Change removeTextByPath(path: List, offset: Number, length: Number) => Change
Remove length characters of text starting at an offset in a Node by its key or path.
setMarkByKey/Path
setMarkByKey/PathsetMarkByKey(key: String, offset: Number, length: Number, mark: Mark, properties: Object) => Change setMarkByPath(path: List, offset: Number, length: Number, mark: Mark, properties: Object) => Change
Set a dictionary of properties on a mark on a Node by its key or path.
setNodeByKey/Path
setNodeByKey/PathsetNodeByKey(key: String, properties: Object) => Change
setNodeByKey(key: String, type: String) => Change setNodeByPath(path: List, properties: Object) => Change
setNodeByPath(path: List, type: String) => Change
Set a dictionary of properties on a Node by its key or path. For convenience, you can pass a type string or properties object.
splitNodeByKey/Path
splitNodeByKey/PathsplitNodeByKey(key: String, offset: Number) => Change splitNodeByPath(path: List, offset: Number) => Change
Split a node by its key or path at an offset.
unwrapInlineByKey/Path
unwrapInlineByKey/PathunwrapInlineByKey(key: String, properties: Object) => Change
unwrapInlineByKey(key: String, type: String) => Change unwrapInlineByPath(path: List, properties: Object) => Change
unwrapInlineByPath(path: List, type: String) => Change
Unwrap all inner content of an Inline node by its key or path that match properties. For convenience, you can pass a type string or properties object.
unwrapBlockByKey/Path
unwrapBlockByKey/PathunwrapBlockByKey(key: String, properties: Object) => Change
unwrapBlockByKey(key: String, type: String) => Change unwrapBlockByPath(path: List, properties: Object) => Change
unwrapBlockByPath(path: List, type: String) => Change
Unwrap all inner content of a Block node by its key or path that match properties. For convenience, you can pass a type string or properties object.
unwrapNodeByKey/Path
unwrapNodeByKey/PathunwrapNodeByKey(key: String) => Change unwrapNodeByPath(path: List) => Change
Unwrap a single node from its parent. If the node is surrounded with siblings, its parent will be split. If the node is the only child, the parent is removed, and simply replaced by the node itself. Cannot unwrap a root node.
wrapBlockByKey/Path
wrapBlockByKey/PathwrapBlockByKey(key: String, properties: Object) => Change
wrapBlockByKey(key: String, type: String) => Change wrapBlockByPath(path: List, properties: Object) => Change
wrapBlockByPath(path: List, type: String) => Change
Wrap the given node in a Block node that match properties. For convenience, you can pass a type string or properties object.
wrapInlineByKey/Path
wrapInlineByKey/PathwrapInlineByKey(key: String, properties: Object) => Change
wrapInlineByKey(key: String, type: String) => Change wrapInlineByPath(path: List, properties: Object) => Change
wrapInlineByPath(path: List, type: String) => Change
Wrap the given node in a Inline node that match properties. For convenience, you can pass a type string or properties object.
wrapNodeByKey/Path
wrapNodeByKey/PathwraNodeByKey(key: String, parent: Node) => Change
wraNodeByPath(path: List, parent: Node) => Change
Wrap the node with the specified key with the parent Node. This will clear all children of the parent.
History Changes
These changes use the history to undo/redo previously made changes.
redo
redoredo() => Change
Move forward one step in the history.
undo
undoundo() => Change
Move backward one step in the history.
snapshotSelection
snapshotSelectionsnapshotSelection() => Change
Snapshot value.selection for undo purposes, useful with delete operations like change.removeNodeByKey(focusBlock.key).undo().
Last updated
Was this helpful?