mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 09:43:58 +02:00
Fix pointRef leaks caused by not unref'ing (#4939)
* Fix pointRef leaks caused by not unref'ing May cause severe performance degradation if more and more point refs need to be updated. * changeset
This commit is contained in:
5
.changeset/khaki-panthers-burn.md
Normal file
5
.changeset/khaki-panthers-burn.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix pointRef leaks caused by not unref'ing
|
@@ -12,6 +12,7 @@ import {
|
|||||||
Ancestor,
|
Ancestor,
|
||||||
} from '..'
|
} from '..'
|
||||||
import { NodeMatch, PropsCompare, PropsMerge } from '../interfaces/editor'
|
import { NodeMatch, PropsCompare, PropsMerge } from '../interfaces/editor'
|
||||||
|
import { PointRef } from '../interfaces/point-ref'
|
||||||
|
|
||||||
export interface NodeTransforms {
|
export interface NodeTransforms {
|
||||||
insertNodes: <T extends Node>(
|
insertNodes: <T extends Node>(
|
||||||
@@ -728,82 +729,85 @@ export const NodeTransforms: NodeTransforms = {
|
|||||||
const beforeRef = Editor.pointRef(editor, at, {
|
const beforeRef = Editor.pointRef(editor, at, {
|
||||||
affinity: 'backward',
|
affinity: 'backward',
|
||||||
})
|
})
|
||||||
const [highest] = Editor.nodes(editor, { at, match, mode, voids })
|
let afterRef: PointRef | undefined
|
||||||
|
try {
|
||||||
|
const [highest] = Editor.nodes(editor, { at, match, mode, voids })
|
||||||
|
|
||||||
if (!highest) {
|
if (!highest) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const voidMatch = Editor.void(editor, { at, mode: 'highest' })
|
const voidMatch = Editor.void(editor, { at, mode: 'highest' })
|
||||||
const nudge = 0
|
const nudge = 0
|
||||||
|
|
||||||
if (!voids && voidMatch) {
|
if (!voids && voidMatch) {
|
||||||
const [voidNode, voidPath] = voidMatch
|
const [voidNode, voidPath] = voidMatch
|
||||||
|
|
||||||
if (Element.isElement(voidNode) && editor.isInline(voidNode)) {
|
if (Element.isElement(voidNode) && editor.isInline(voidNode)) {
|
||||||
let after = Editor.after(editor, voidPath)
|
let after = Editor.after(editor, voidPath)
|
||||||
|
|
||||||
if (!after) {
|
if (!after) {
|
||||||
const text = { text: '' }
|
const text = { text: '' }
|
||||||
const afterPath = Path.next(voidPath)
|
const afterPath = Path.next(voidPath)
|
||||||
Transforms.insertNodes(editor, text, { at: afterPath, voids })
|
Transforms.insertNodes(editor, text, { at: afterPath, voids })
|
||||||
after = Editor.point(editor, afterPath)!
|
after = Editor.point(editor, afterPath)!
|
||||||
|
}
|
||||||
|
|
||||||
|
at = after
|
||||||
|
always = true
|
||||||
}
|
}
|
||||||
|
|
||||||
at = after
|
const siblingHeight = at.path.length - voidPath.length
|
||||||
|
height = siblingHeight + 1
|
||||||
always = true
|
always = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const siblingHeight = at.path.length - voidPath.length
|
afterRef = Editor.pointRef(editor, at)
|
||||||
height = siblingHeight + 1
|
const depth = at.path.length - height
|
||||||
always = true
|
const [, highestPath] = highest
|
||||||
}
|
const lowestPath = at.path.slice(0, depth)
|
||||||
|
let position = height === 0 ? at.offset : at.path[depth] + nudge
|
||||||
|
|
||||||
const afterRef = Editor.pointRef(editor, at)
|
for (const [node, path] of Editor.levels(editor, {
|
||||||
const depth = at.path.length - height
|
at: lowestPath,
|
||||||
const [, highestPath] = highest
|
reverse: true,
|
||||||
const lowestPath = at.path.slice(0, depth)
|
voids,
|
||||||
let position = height === 0 ? at.offset : at.path[depth] + nudge
|
})) {
|
||||||
|
let split = false
|
||||||
|
|
||||||
for (const [node, path] of Editor.levels(editor, {
|
if (
|
||||||
at: lowestPath,
|
path.length < highestPath.length ||
|
||||||
reverse: true,
|
path.length === 0 ||
|
||||||
voids,
|
(!voids && Editor.isVoid(editor, node))
|
||||||
})) {
|
) {
|
||||||
let split = false
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
const point = beforeRef.current!
|
||||||
path.length < highestPath.length ||
|
const isEnd = Editor.isEnd(editor, point, path)
|
||||||
path.length === 0 ||
|
|
||||||
(!voids && Editor.isVoid(editor, node))
|
if (always || !beforeRef || !Editor.isEdge(editor, point, path)) {
|
||||||
) {
|
split = true
|
||||||
break
|
const properties = Node.extractProps(node)
|
||||||
|
editor.apply({
|
||||||
|
type: 'split_node',
|
||||||
|
path,
|
||||||
|
position,
|
||||||
|
properties,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
position = path[path.length - 1] + (split || isEnd ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
const point = beforeRef.current!
|
if (options.at == null) {
|
||||||
const isEnd = Editor.isEnd(editor, point, path)
|
const point = afterRef.current || Editor.end(editor, [])
|
||||||
|
Transforms.select(editor, point)
|
||||||
if (always || !beforeRef || !Editor.isEdge(editor, point, path)) {
|
|
||||||
split = true
|
|
||||||
const properties = Node.extractProps(node)
|
|
||||||
editor.apply({
|
|
||||||
type: 'split_node',
|
|
||||||
path,
|
|
||||||
position,
|
|
||||||
properties,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
position = path[path.length - 1] + (split || isEnd ? 1 : 0)
|
beforeRef.unref()
|
||||||
|
afterRef?.unref()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.at == null) {
|
|
||||||
const point = afterRef.current || Editor.end(editor, [])
|
|
||||||
Transforms.select(editor, point)
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeRef.unref()
|
|
||||||
afterRef.unref()
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -214,9 +214,9 @@ export const TextTransforms: TextTransforms = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const point = reverse
|
const startUnref = startRef.unref()
|
||||||
? startRef.unref() || endRef.unref()
|
const endUnref = endRef.unref()
|
||||||
: endRef.unref() || startRef.unref()
|
const point = reverse ? startUnref || endUnref : endUnref || startUnref
|
||||||
|
|
||||||
if (options.at == null && point) {
|
if (options.at == null && point) {
|
||||||
Transforms.select(editor, point)
|
Transforms.select(editor, point)
|
||||||
|
Reference in New Issue
Block a user