1
0
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:
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, 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()
}) })
}, },

View File

@@ -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)