1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-11 01:33: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:
Alex
2022-04-12 18:56:51 +02:00
committed by GitHub
parent d460bb42f0
commit c39c8082a9
3 changed files with 71 additions and 62 deletions

View File

@@ -0,0 +1,5 @@
---
'slate': patch
---
Fix pointRef leaks caused by not unref'ing

View File

@@ -12,6 +12,7 @@ import {
Ancestor,
} from '..'
import { NodeMatch, PropsCompare, PropsMerge } from '../interfaces/editor'
import { PointRef } from '../interfaces/point-ref'
export interface NodeTransforms {
insertNodes: <T extends Node>(
@@ -728,82 +729,85 @@ export const NodeTransforms: NodeTransforms = {
const beforeRef = Editor.pointRef(editor, at, {
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) {
return
}
if (!highest) {
return
}
const voidMatch = Editor.void(editor, { at, mode: 'highest' })
const nudge = 0
const voidMatch = Editor.void(editor, { at, mode: 'highest' })
const nudge = 0
if (!voids && voidMatch) {
const [voidNode, voidPath] = voidMatch
if (!voids && voidMatch) {
const [voidNode, voidPath] = voidMatch
if (Element.isElement(voidNode) && editor.isInline(voidNode)) {
let after = Editor.after(editor, voidPath)
if (Element.isElement(voidNode) && editor.isInline(voidNode)) {
let after = Editor.after(editor, voidPath)
if (!after) {
const text = { text: '' }
const afterPath = Path.next(voidPath)
Transforms.insertNodes(editor, text, { at: afterPath, voids })
after = Editor.point(editor, afterPath)!
if (!after) {
const text = { text: '' }
const afterPath = Path.next(voidPath)
Transforms.insertNodes(editor, text, { at: afterPath, voids })
after = Editor.point(editor, afterPath)!
}
at = after
always = true
}
at = after
const siblingHeight = at.path.length - voidPath.length
height = siblingHeight + 1
always = true
}
const siblingHeight = at.path.length - voidPath.length
height = siblingHeight + 1
always = true
}
afterRef = Editor.pointRef(editor, at)
const depth = at.path.length - height
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)
const depth = at.path.length - height
const [, highestPath] = highest
const lowestPath = at.path.slice(0, depth)
let position = height === 0 ? at.offset : at.path[depth] + nudge
for (const [node, path] of Editor.levels(editor, {
at: lowestPath,
reverse: true,
voids,
})) {
let split = false
for (const [node, path] of Editor.levels(editor, {
at: lowestPath,
reverse: true,
voids,
})) {
let split = false
if (
path.length < highestPath.length ||
path.length === 0 ||
(!voids && Editor.isVoid(editor, node))
) {
break
}
if (
path.length < highestPath.length ||
path.length === 0 ||
(!voids && Editor.isVoid(editor, node))
) {
break
const point = beforeRef.current!
const isEnd = Editor.isEnd(editor, point, path)
if (always || !beforeRef || !Editor.isEdge(editor, point, path)) {
split = true
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!
const isEnd = Editor.isEnd(editor, point, path)
if (always || !beforeRef || !Editor.isEdge(editor, point, path)) {
split = true
const properties = Node.extractProps(node)
editor.apply({
type: 'split_node',
path,
position,
properties,
})
if (options.at == null) {
const point = afterRef.current || Editor.end(editor, [])
Transforms.select(editor, point)
}
position = path[path.length - 1] + (split || isEnd ? 1 : 0)
} finally {
beforeRef.unref()
afterRef?.unref()
}
if (options.at == null) {
const point = afterRef.current || Editor.end(editor, [])
Transforms.select(editor, point)
}
beforeRef.unref()
afterRef.unref()
})
},

View File

@@ -214,9 +214,9 @@ export const TextTransforms: TextTransforms = {
})
}
const point = reverse
? startRef.unref() || endRef.unref()
: endRef.unref() || startRef.unref()
const startUnref = startRef.unref()
const endUnref = endRef.unref()
const point = reverse ? startUnref || endUnref : endUnref || startUnref
if (options.at == null && point) {
Transforms.select(editor, point)