mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-05 14:57:25 +02:00
chore: add shouldMergeNodesRemovePrevNode (#5621)
* chore: add shouldMergeNodesRemovePrevNode * fix: typo
This commit is contained in:
5
.changeset/early-mayflies-grow.md
Normal file
5
.changeset/early-mayflies-grow.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add a `shouldMergeNodesRemovePrevNode` editor method to control when `Transforms.mergeNodes` should remove the previous node rather than carrying out a merge operation.
|
@@ -57,6 +57,7 @@ import {
|
|||||||
rangeRef,
|
rangeRef,
|
||||||
rangeRefs,
|
rangeRefs,
|
||||||
setNormalizing,
|
setNormalizing,
|
||||||
|
shouldMergeNodesRemovePrevNode,
|
||||||
start,
|
start,
|
||||||
string,
|
string,
|
||||||
unhangRange,
|
unhangRange,
|
||||||
@@ -181,6 +182,8 @@ export const createEditor = (): Editor => {
|
|||||||
void: (...args) => getVoid(editor, ...args),
|
void: (...args) => getVoid(editor, ...args),
|
||||||
withoutNormalizing: (...args) => withoutNormalizing(editor, ...args),
|
withoutNormalizing: (...args) => withoutNormalizing(editor, ...args),
|
||||||
wrapNodes: (...args) => wrapNodes(editor, ...args),
|
wrapNodes: (...args) => wrapNodes(editor, ...args),
|
||||||
|
shouldMergeNodesRemovePrevNode: (...args) =>
|
||||||
|
shouldMergeNodesRemovePrevNode(editor, ...args),
|
||||||
}
|
}
|
||||||
|
|
||||||
return editor
|
return editor
|
||||||
|
@@ -52,3 +52,4 @@ export * from './start'
|
|||||||
export * from './string'
|
export * from './string'
|
||||||
export * from './unhang-range'
|
export * from './unhang-range'
|
||||||
export * from './without-normalizing'
|
export * from './without-normalizing'
|
||||||
|
export * from './should-merge-nodes-remove-prev-node'
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
import { EditorInterface, Element, Editor, Text } from '../interfaces'
|
||||||
|
|
||||||
|
export const shouldMergeNodesRemovePrevNode: EditorInterface['shouldMergeNodesRemovePrevNode'] =
|
||||||
|
(editor, [prevNode, prevPath], [curNode, curNodePath]) => {
|
||||||
|
// If the target node that we're merging with is empty, remove it instead
|
||||||
|
// of merging the two. This is a common rich text editor behavior to
|
||||||
|
// prevent losing formatting when deleting entire nodes when you have a
|
||||||
|
// hanging selection.
|
||||||
|
// if prevNode is first child in parent,don't remove it.
|
||||||
|
|
||||||
|
return (
|
||||||
|
(Element.isElement(prevNode) && Editor.isEmpty(editor, prevNode)) ||
|
||||||
|
(Text.isText(prevNode) &&
|
||||||
|
prevNode.text === '' &&
|
||||||
|
prevPath[prevPath.length - 1] !== 0)
|
||||||
|
)
|
||||||
|
}
|
@@ -167,6 +167,9 @@ export interface BaseEditor {
|
|||||||
string: OmitFirstArg<typeof Editor.string>
|
string: OmitFirstArg<typeof Editor.string>
|
||||||
unhangRange: OmitFirstArg<typeof Editor.unhangRange>
|
unhangRange: OmitFirstArg<typeof Editor.unhangRange>
|
||||||
void: OmitFirstArg<typeof Editor.void>
|
void: OmitFirstArg<typeof Editor.void>
|
||||||
|
shouldMergeNodesRemovePrevNode: OmitFirstArg<
|
||||||
|
typeof Editor.shouldMergeNodesRemovePrevNode
|
||||||
|
>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Editor = ExtendedType<'Editor', BaseEditor>
|
export type Editor = ExtendedType<'Editor', BaseEditor>
|
||||||
@@ -709,6 +712,15 @@ export interface EditorInterface {
|
|||||||
* Call a function, deferring normalization until after it completes.
|
* Call a function, deferring normalization until after it completes.
|
||||||
*/
|
*/
|
||||||
withoutNormalizing: (editor: Editor, fn: () => void) => void
|
withoutNormalizing: (editor: Editor, fn: () => void) => void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a function, Determine whether or not remove the previous node when merge.
|
||||||
|
*/
|
||||||
|
shouldMergeNodesRemovePrevNode: (
|
||||||
|
editor: Editor,
|
||||||
|
prevNodeEntry: NodeEntry,
|
||||||
|
curNodeEntry: NodeEntry
|
||||||
|
) => boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-redeclare
|
// eslint-disable-next-line no-redeclare
|
||||||
@@ -953,6 +965,9 @@ export const Editor: EditorInterface = {
|
|||||||
withoutNormalizing(editor, fn: () => void) {
|
withoutNormalizing(editor, fn: () => void) {
|
||||||
editor.withoutNormalizing(fn)
|
editor.withoutNormalizing(fn)
|
||||||
},
|
},
|
||||||
|
shouldMergeNodesRemovePrevNode: (editor, prevNode, curNode) => {
|
||||||
|
return editor.shouldMergeNodesRemovePrevNode(prevNode, curNode)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -128,17 +128,7 @@ export const mergeNodes: NodeTransforms['mergeNodes'] = (
|
|||||||
Transforms.removeNodes(editor, { at: emptyRef.current!, voids })
|
Transforms.removeNodes(editor, { at: emptyRef.current!, voids })
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the target node that we're merging with is empty, remove it instead
|
if (Editor.shouldMergeNodesRemovePrevNode(editor, prev, current)) {
|
||||||
// of merging the two. This is a common rich text editor behavior to
|
|
||||||
// prevent losing formatting when deleting entire nodes when you have a
|
|
||||||
// hanging selection.
|
|
||||||
// if prevNode is first child in parent,don't remove it.
|
|
||||||
if (
|
|
||||||
(Element.isElement(prevNode) && Editor.isEmpty(editor, prevNode)) ||
|
|
||||||
(Text.isText(prevNode) &&
|
|
||||||
prevNode.text === '' &&
|
|
||||||
prevPath[prevPath.length - 1] !== 0)
|
|
||||||
) {
|
|
||||||
Transforms.removeNodes(editor, { at: prevPath, voids })
|
Transforms.removeNodes(editor, { at: prevPath, voids })
|
||||||
} else {
|
} else {
|
||||||
editor.apply({
|
editor.apply({
|
||||||
|
Reference in New Issue
Block a user