1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-02 19:52:32 +02:00

Transform.insertNodes & Transform.insertFragment performance optimize (#5543)

* feat: insertNodes & insertFragment performance optimize

* chore: change set

* feat: add unit test

---------

Co-authored-by: mainhanu@outlook.com <xingchi.mxc@alibaba-inc.com>
This commit is contained in:
mainhanu
2024-02-07 20:01:16 +08:00
committed by GitHub
parent c2ae1eda91
commit 3aaf3b517c
73 changed files with 381 additions and 175 deletions

View File

@@ -0,0 +1,5 @@
---
'slate': minor
---
Transform.insertNodes & Transform.insertFragment performance optimize

View File

@@ -1,11 +1,13 @@
import { PathRef } from '../interfaces/path-ref' import { PathRef } from '../interfaces/path-ref'
import { PointRef } from '../interfaces/point-ref' import { PointRef } from '../interfaces/point-ref'
import { RangeRef } from '../interfaces/range-ref' import { RangeRef } from '../interfaces/range-ref'
import { DIRTY_PATH_KEYS, DIRTY_PATHS, FLUSHING } from '../utils/weak-maps' import { FLUSHING } from '../utils/weak-maps'
import { Path } from '../interfaces/path' import { Path } from '../interfaces/path'
import { Transforms } from '../interfaces/transforms' import { Transforms } from '../interfaces/transforms'
import { WithEditorFirstArg } from '../utils/types' import { WithEditorFirstArg } from '../utils/types'
import { Editor } from '../interfaces/editor' import { Editor } from '../interfaces/editor'
import { isBatchingDirtyPaths } from './batch-dirty-paths'
import { updateDirtyPaths } from './update-dirty-paths'
export const apply: WithEditorFirstArg<Editor['apply']> = (editor, op) => { export const apply: WithEditorFirstArg<Editor['apply']> = (editor, op) => {
for (const ref of Editor.pathRefs(editor)) { for (const ref of Editor.pathRefs(editor)) {
@@ -20,41 +22,14 @@ export const apply: WithEditorFirstArg<Editor['apply']> = (editor, op) => {
RangeRef.transform(ref, op) RangeRef.transform(ref, op)
} }
const oldDirtyPaths = DIRTY_PATHS.get(editor) || [] // update dirty paths
const oldDirtyPathKeys = DIRTY_PATH_KEYS.get(editor) || new Set() if (!isBatchingDirtyPaths(editor)) {
let dirtyPaths: Path[] const transform = Path.operationCanTransformPath(op)
let dirtyPathKeys: Set<string> ? (p: Path) => Path.transform(p, op)
: undefined
const add = (path: Path | null) => { updateDirtyPaths(editor, editor.getDirtyPaths(op), transform)
if (path) {
const key = path.join(',')
if (!dirtyPathKeys.has(key)) {
dirtyPathKeys.add(key)
dirtyPaths.push(path)
}
}
} }
if (Path.operationCanTransformPath(op)) {
dirtyPaths = []
dirtyPathKeys = new Set()
for (const path of oldDirtyPaths) {
const newPath = Path.transform(path, op)
add(newPath)
}
} else {
dirtyPaths = oldDirtyPaths
dirtyPathKeys = oldDirtyPathKeys
}
const newDirtyPaths = editor.getDirtyPaths(op)
for (const path of newDirtyPaths) {
add(path)
}
DIRTY_PATHS.set(editor, dirtyPaths)
DIRTY_PATH_KEYS.set(editor, dirtyPathKeys)
Transforms.transform(editor, op) Transforms.transform(editor, op)
editor.operations.push(op) editor.operations.push(op)
Editor.normalize(editor, { Editor.normalize(editor, {

View File

@@ -0,0 +1,24 @@
// perf
import { Editor } from '../interfaces/editor'
const BATCHING_DIRTY_PATHS: WeakMap<Editor, boolean> = new WeakMap()
export const isBatchingDirtyPaths = (editor: Editor) => {
return BATCHING_DIRTY_PATHS.get(editor) || false
}
export const batchDirtyPaths = (
editor: Editor,
fn: () => void,
update: () => void
) => {
const value = BATCHING_DIRTY_PATHS.get(editor) || false
BATCHING_DIRTY_PATHS.set(editor, true)
try {
fn()
update()
} finally {
BATCHING_DIRTY_PATHS.set(editor, value)
}
}

View File

@@ -0,0 +1,50 @@
import { DIRTY_PATH_KEYS, DIRTY_PATHS } from '../utils/weak-maps'
import { Path } from '../interfaces/path'
import { Editor } from '../interfaces/editor'
/**
* update editor dirty paths
*
* @param newDirtyPaths: Path[]; new dirty paths
* @param transform: (p: Path) => Path | null; how to transform existing dirty paths
*/
export function updateDirtyPaths(
editor: Editor,
newDirtyPaths: Path[],
transform?: (p: Path) => Path | null
) {
const oldDirtyPaths = DIRTY_PATHS.get(editor) || []
const oldDirtyPathKeys = DIRTY_PATH_KEYS.get(editor) || new Set()
let dirtyPaths: Path[]
let dirtyPathKeys: Set<string>
const add = (path: Path | null) => {
if (path) {
const key = path.join(',')
if (!dirtyPathKeys.has(key)) {
dirtyPathKeys.add(key)
dirtyPaths.push(path)
}
}
}
if (transform) {
dirtyPaths = []
dirtyPathKeys = new Set()
for (const path of oldDirtyPaths) {
const newPath = transform(path)
add(newPath)
}
} else {
dirtyPaths = oldDirtyPaths
dirtyPathKeys = oldDirtyPathKeys
}
for (const path of newDirtyPaths) {
add(path)
}
DIRTY_PATHS.set(editor, dirtyPaths)
DIRTY_PATH_KEYS.set(editor, dirtyPathKeys)
}

View File

@@ -9,6 +9,7 @@ export interface NodeInsertNodesOptions<T extends Node> {
hanging?: boolean hanging?: boolean
select?: boolean select?: boolean
voids?: boolean voids?: boolean
batchDirty?: boolean
} }
export interface NodeTransforms { export interface NodeTransforms {

View File

@@ -15,6 +15,7 @@ export interface TextInsertFragmentOptions {
at?: Location at?: Location
hanging?: boolean hanging?: boolean
voids?: boolean voids?: boolean
batchDirty?: boolean
} }
export interface TextInsertTextOptions { export interface TextInsertTextOptions {

View File

@@ -8,6 +8,9 @@ import { Text } from '../interfaces/text'
import { Element } from '../interfaces/element' import { Element } from '../interfaces/element'
import { Path } from '../interfaces/path' import { Path } from '../interfaces/path'
import { getDefaultInsertLocation } from '../utils' import { getDefaultInsertLocation } from '../utils'
import { batchDirtyPaths } from '../core/batch-dirty-paths'
import { BaseInsertNodeOperation } from '../interfaces'
import { updateDirtyPaths } from '../core/update-dirty-paths'
export const insertNodes: NodeTransforms['insertNodes'] = ( export const insertNodes: NodeTransforms['insertNodes'] = (
editor, editor,
@@ -15,7 +18,12 @@ export const insertNodes: NodeTransforms['insertNodes'] = (
options = {} options = {}
) => { ) => {
Editor.withoutNormalizing(editor, () => { Editor.withoutNormalizing(editor, () => {
const { hanging = false, voids = false, mode = 'lowest' } = options const {
hanging = false,
voids = false,
mode = 'lowest',
batchDirty = true,
} = options
let { at, match, select } = options let { at, match, select } = options
if (Node.isNode(nodes)) { if (Node.isNode(nodes)) {
@@ -91,12 +99,61 @@ export const insertNodes: NodeTransforms['insertNodes'] = (
return return
} }
for (const node of nodes) { if (batchDirty) {
const path = parentPath.concat(index) // PERF: batch update dirty paths
index++ // batched ops used to transform existing dirty paths
editor.apply({ type: 'insert_node', path, node }) const batchedOps: BaseInsertNodeOperation[] = []
at = Path.next(at) const newDirtyPaths: Path[] = Path.levels(parentPath)
batchDirtyPaths(
editor,
() => {
for (const node of nodes as Node[]) {
const path = parentPath.concat(index)
index++
const op: BaseInsertNodeOperation = {
type: 'insert_node',
path,
node,
}
editor.apply(op)
at = Path.next(at as Path)
batchedOps.push(op)
if (!Text.isText) {
newDirtyPaths.push(path)
} else {
newDirtyPaths.push(
...Array.from(Node.nodes(node), ([, p]) => path.concat(p))
)
}
}
},
() => {
updateDirtyPaths(editor, newDirtyPaths, p => {
let newPath: Path | null = p
for (const op of batchedOps) {
if (Path.operationCanTransformPath(op)) {
newPath = Path.transform(newPath, op)
if (!newPath) {
return null
}
}
}
return newPath
})
}
)
} else {
for (const node of nodes as Node[]) {
const path = parentPath.concat(index)
index++
editor.apply({ type: 'insert_node', path, node })
at = Path.next(at as Path)
}
} }
at = Path.previous(at) at = Path.previous(at)
if (select) { if (select) {

View File

@@ -15,7 +15,7 @@ export const insertFragment: TextTransforms['insertFragment'] = (
) => { ) => {
Editor.withoutNormalizing(editor, () => { Editor.withoutNormalizing(editor, () => {
const { hanging = false, voids = false } = options const { hanging = false, voids = false } = options
let { at = getDefaultInsertLocation(editor) } = options let { at = getDefaultInsertLocation(editor), batchDirty = true } = options
if (!fragment.length) { if (!fragment.length) {
return return
@@ -187,6 +187,7 @@ export const insertFragment: TextTransforms['insertFragment'] = (
match: n => Text.isText(n) || Editor.isInline(editor, n), match: n => Text.isText(n) || Editor.isInline(editor, n),
mode: 'highest', mode: 'highest',
voids, voids,
batchDirty,
}) })
if (isBlockEmpty && !starts.length && middles.length && !ends.length) { if (isBlockEmpty && !starts.length && middles.length && !ends.length) {
@@ -198,6 +199,7 @@ export const insertFragment: TextTransforms['insertFragment'] = (
match: n => Element.isElement(n) && Editor.isBlock(editor, n), match: n => Element.isElement(n) && Editor.isBlock(editor, n),
mode: 'lowest', mode: 'lowest',
voids, voids,
batchDirty,
}) })
Transforms.insertNodes(editor, ends, { Transforms.insertNodes(editor, ends, {
@@ -205,6 +207,7 @@ export const insertFragment: TextTransforms['insertFragment'] = (
match: n => Text.isText(n) || Editor.isInline(editor, n), match: n => Text.isText(n) || Editor.isInline(editor, n),
mode: 'highest', mode: 'highest',
voids, voids,
batchDirty,
}) })
if (!options.at) { if (!options.at) {

View File

@@ -1,6 +1,7 @@
import assert from 'assert' import assert from 'assert'
import { cloneDeep } from 'lodash'
import { fixtures } from '../../../support/fixtures' import { fixtures } from '../../../support/fixtures'
import { Editor } from 'slate' import { Editor, createEditor } from 'slate'
import { createHyperscript } from 'slate-hyperscript' import { createHyperscript } from 'slate-hyperscript'
describe('slate', () => { describe('slate', () => {
@@ -45,6 +46,31 @@ describe('slate', () => {
const result = test(input) const result = test(input)
assert.deepEqual(result, output) assert.deepEqual(result, output)
}) })
// make sure with or without batchDirty, the normalize result is the same
const testBatchDirty = ({ module }) => {
const { input, run } = module
const input2 = createEditor()
input2.children = cloneDeep(input.children)
input2.selection = cloneDeep(input.selection)
const dirties1 = []
const dirties2 = []
const editor1 = withBatchTest(withTest(input), dirties1)
const editor2 = withBatchTest(withTest(input2), dirties2)
run(editor1, { batchDirty: true })
run(editor2, { batchDirty: false })
assert.equal(dirties1.join(' '), dirties2.join(' '))
}
fixtures(__dirname, 'transforms/insertNodes', ({ module }) => {
testBatchDirty({ module })
})
fixtures(__dirname, 'transforms/insertFragment', ({ module }) => {
testBatchDirty({ module })
})
}) })
const withTest = editor => { const withTest = editor => {
const { isInline, isVoid, isElementReadOnly, isSelectable } = editor const { isInline, isVoid, isElementReadOnly, isSelectable } = editor
@@ -62,6 +88,14 @@ const withTest = editor => {
} }
return editor return editor
} }
const withBatchTest = (editor, dirties) => {
const { normalizeNode } = editor
editor.normalizeNode = ([node, path]) => {
dirties.push(JSON.stringify(path))
normalizeNode([node, path])
}
return editor
}
export const jsx = createHyperscript({ export const jsx = createHyperscript({
elements: { elements: {
block: {}, block: {},

View File

@@ -2,7 +2,7 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
@@ -11,7 +11,8 @@ export const run = editor => {
</block> </block>
<block>two</block> <block>two</block>
<block>three</block> <block>three</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>one</block> <block>one</block>
<block>two</block> <block>two</block>
<block>three</block> <block>three</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -8,8 +8,8 @@ const fragment = (
<block>two</block> <block>two</block>
</fragment> </fragment>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, fragment) Transforms.insertFragment(editor, fragment, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>one</block> <block>one</block>
<block>two</block> <block>two</block>
<block>three</block> <block>three</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>one</block> <block>one</block>
<block>two</block> <block>two</block>
<block>three</block> <block>three</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>one</block> <block>one</block>
<block>two</block> <block>two</block>
<block>three</block> <block>three</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,7 +2,7 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
@@ -15,7 +15,8 @@ export const run = editor => {
<block> <block>
seven<inline>eight</inline>nine seven<inline>eight</inline>nine
</block> </block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>fragment</inline> <inline>fragment</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<inline>one</inline> <inline>one</inline>
<inline>two</inline> <inline>two</inline>
<inline>three</inline> <inline>three</inline>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
one one
<inline>two</inline> <inline>two</inline>
three three
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<block> <block>
<block>3</block> <block>3</block>
<block>4</block> <block>4</block>
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
<text>three</text> <text>three</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>two</block> <block>two</block>
<text>three</text> <text>three</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
<text>three</text> <text>three</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
<text>three</text> <text>three</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,14 +2,15 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<block>two</block> <block>two</block>
<text>three</text> <text>three</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<block>one</block> <block>one</block>
<text>two</text> <text>two</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,7 +2,7 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<block> <block>
@@ -16,7 +16,8 @@ export const run = editor => {
</block> </block>
</block> </block>
</block> </block>
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,7 +2,7 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<block> <block>
@@ -12,7 +12,8 @@ export const run = editor => {
<block>2</block> <block>2</block>
</block> </block>
</block> </block>
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,7 +2,7 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<block> <block>
@@ -12,7 +12,8 @@ export const run = editor => {
<block>New 2</block> <block>New 2</block>
</block> </block>
</block> </block>
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,13 +2,14 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment( Transforms.insertFragment(
editor, editor,
<fragment> <fragment>
<text>one</text> <text>one</text>
<text>two</text> <text>two</text>
</fragment> </fragment>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,8 +2,8 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>) Transforms.insertFragment(editor, <fragment>fragment</fragment>, options)
} }
export const input = ( export const input = (
<editor> <editor>

View File

@@ -2,9 +2,10 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>, { Transforms.insertFragment(editor, <fragment>fragment</fragment>, {
voids: true, voids: true,
...options,
}) })
} }
export const input = ( export const input = (

View File

@@ -2,9 +2,10 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertFragment(editor, <fragment>fragment</fragment>, { Transforms.insertFragment(editor, <fragment>fragment</fragment>, {
voids: true, voids: true,
...options,
}) })
} }
export const input = ( export const input = (

View File

@@ -10,12 +10,13 @@ export const input = (
<block>not empty</block> <block>not empty</block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block> </block>,
options
) )
} }
export const output = ( export const output = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block> </block>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -9,12 +9,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const output = ( export const output = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -2,12 +2,13 @@
import { Transforms } from 'slate' import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text /> <text />
</inline> </inline>,
options
) )
} }
export const input = ( export const input = (

View File

@@ -10,13 +10,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block>, </block>,
{ at: [0] } { at: [0], ...options }
) )
} }
export const output = ( export const output = (

View File

@@ -10,13 +10,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline> <inline>
<text /> <text />
</inline>, </inline>,
{ at: [0, 0] } { at: [0, 0], ...options }
) )
} }
export const output = ( export const output = (

View File

@@ -11,13 +11,17 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, [ Transforms.insertNodes(
<inline> editor,
<text /> [
</inline>, <inline>
<text>world</text>, <text />
]) </inline>,
<text>world</text>,
],
options
)
} }
export const output = ( export const output = (
<editor> <editor>

View File

@@ -10,13 +10,17 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, [ Transforms.insertNodes(
<inline> editor,
<text /> [
</inline>, <inline>
<text>world</text>, <text />
]) </inline>,
<text>world</text>,
],
options
)
} }
export const output = ( export const output = (
<editor> <editor>

View File

@@ -10,9 +10,10 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, [<block>two</block>, <block>three</block>], { Transforms.insertNodes(editor, [<block>two</block>, <block>three</block>], {
at: [0], at: [0],
...options,
}) })
} }
export const output = ( export const output = (

View File

@@ -10,8 +10,11 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, <text>another</text>, { at: [0, 0] }) Transforms.insertNodes(editor, <text>another</text>, {
at: [0, 0],
...options,
})
} }
export const output = ( export const output = (
<editor> <editor>

View File

@@ -10,13 +10,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block> <block>
<text /> <text />
</block>, </block>,
{ at: [0], select: true } { at: [0], select: true, ...options }
) )
} }
export const output = ( export const output = (

View File

@@ -3,8 +3,8 @@ import { Transforms } from 'slate'
import { jsx } from '../../..' import { jsx } from '../../..'
export const input = <editor /> export const input = <editor />
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, <block>one</block>) Transforms.insertNodes(editor, <block>one</block>, options)
} }
export const output = ( export const output = (
<editor> <editor>

View File

@@ -7,8 +7,8 @@ export const input = (
<block>one</block> <block>one</block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, <block>two</block>) Transforms.insertNodes(editor, <block>two</block>, options)
} }
export const output = ( export const output = (
<editor> <editor>

View File

@@ -10,13 +10,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block void> <block void>
<text>two</text> <text>two</text>
</block>, </block>,
{ at: [1], select: true } { at: [1], select: true, ...options }
) )
} }
export const output = ( export const output = (

View File

@@ -10,14 +10,15 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block void> <block void>
<block> <block>
<text>two</text> <text>two</text>
</block> </block>
</block> </block>,
options
) )
} }
export const output = ( export const output = (

View File

@@ -10,12 +10,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<block void> <block void>
<text>two</text> <text>two</text>
</block> </block>,
options
) )
} }
export const output = ( export const output = (

View File

@@ -14,12 +14,13 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes( Transforms.insertNodes(
editor, editor,
<inline void> <inline void>
<text>four</text> <text>four</text>
</inline> </inline>,
options
) )
} }
export const output = ( export const output = (

View File

@@ -10,10 +10,11 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, <text>two</text>, { Transforms.insertNodes(editor, <text>two</text>, {
at: [0, 1], at: [0, 1],
voids: true, voids: true,
options,
}) })
} }
export const output = ( export const output = (

View File

@@ -14,10 +14,11 @@ export const input = (
</block> </block>
</editor> </editor>
) )
export const run = editor => { export const run = (editor, options = {}) => {
Transforms.insertNodes(editor, <text>four</text>, { Transforms.insertNodes(editor, <text>four</text>, {
at: [0, 1, 1], at: [0, 1, 1],
voids: true, voids: true,
options,
}) })
} }
export const output = ( export const output = (