mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-31 15:24:31 +03:00
Lexical: Imported core lexical libs
Imported at 0.17.1, Modified to work in-app. Added & configured test dependancies. Tests need to be altered to avoid using non-included deps including react dependancies.
This commit is contained in:
125
resources/js/wysiwyg/lexical/core/LexicalGC.ts
Normal file
125
resources/js/wysiwyg/lexical/core/LexicalGC.ts
Normal file
@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
import type {ElementNode} from '.';
|
||||
import type {LexicalEditor} from './LexicalEditor';
|
||||
import type {EditorState} from './LexicalEditorState';
|
||||
import type {NodeKey, NodeMap} from './LexicalNode';
|
||||
|
||||
import {$isElementNode} from '.';
|
||||
import {cloneDecorators} from './LexicalUtils';
|
||||
|
||||
export function $garbageCollectDetachedDecorators(
|
||||
editor: LexicalEditor,
|
||||
pendingEditorState: EditorState,
|
||||
): void {
|
||||
const currentDecorators = editor._decorators;
|
||||
const pendingDecorators = editor._pendingDecorators;
|
||||
let decorators = pendingDecorators || currentDecorators;
|
||||
const nodeMap = pendingEditorState._nodeMap;
|
||||
let key;
|
||||
|
||||
for (key in decorators) {
|
||||
if (!nodeMap.has(key)) {
|
||||
if (decorators === currentDecorators) {
|
||||
decorators = cloneDecorators(editor);
|
||||
}
|
||||
|
||||
delete decorators[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type IntentionallyMarkedAsDirtyElement = boolean;
|
||||
|
||||
function $garbageCollectDetachedDeepChildNodes(
|
||||
node: ElementNode,
|
||||
parentKey: NodeKey,
|
||||
prevNodeMap: NodeMap,
|
||||
nodeMap: NodeMap,
|
||||
nodeMapDelete: Array<NodeKey>,
|
||||
dirtyNodes: Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
|
||||
): void {
|
||||
let child = node.getFirstChild();
|
||||
|
||||
while (child !== null) {
|
||||
const childKey = child.__key;
|
||||
// TODO Revise condition below, redundant? LexicalNode already cleans up children when moving Nodes
|
||||
if (child.__parent === parentKey) {
|
||||
if ($isElementNode(child)) {
|
||||
$garbageCollectDetachedDeepChildNodes(
|
||||
child,
|
||||
childKey,
|
||||
prevNodeMap,
|
||||
nodeMap,
|
||||
nodeMapDelete,
|
||||
dirtyNodes,
|
||||
);
|
||||
}
|
||||
|
||||
// If we have created a node and it was dereferenced, then also
|
||||
// remove it from out dirty nodes Set.
|
||||
if (!prevNodeMap.has(childKey)) {
|
||||
dirtyNodes.delete(childKey);
|
||||
}
|
||||
nodeMapDelete.push(childKey);
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
export function $garbageCollectDetachedNodes(
|
||||
prevEditorState: EditorState,
|
||||
editorState: EditorState,
|
||||
dirtyLeaves: Set<NodeKey>,
|
||||
dirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
|
||||
): void {
|
||||
const prevNodeMap = prevEditorState._nodeMap;
|
||||
const nodeMap = editorState._nodeMap;
|
||||
// Store dirtyElements in a queue for later deletion; deleting dirty subtrees too early will
|
||||
// hinder accessing .__next on child nodes
|
||||
const nodeMapDelete: Array<NodeKey> = [];
|
||||
|
||||
for (const [nodeKey] of dirtyElements) {
|
||||
const node = nodeMap.get(nodeKey);
|
||||
if (node !== undefined) {
|
||||
// Garbage collect node and its children if they exist
|
||||
if (!node.isAttached()) {
|
||||
if ($isElementNode(node)) {
|
||||
$garbageCollectDetachedDeepChildNodes(
|
||||
node,
|
||||
nodeKey,
|
||||
prevNodeMap,
|
||||
nodeMap,
|
||||
nodeMapDelete,
|
||||
dirtyElements,
|
||||
);
|
||||
}
|
||||
// If we have created a node and it was dereferenced, then also
|
||||
// remove it from out dirty nodes Set.
|
||||
if (!prevNodeMap.has(nodeKey)) {
|
||||
dirtyElements.delete(nodeKey);
|
||||
}
|
||||
nodeMapDelete.push(nodeKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const nodeKey of nodeMapDelete) {
|
||||
nodeMap.delete(nodeKey);
|
||||
}
|
||||
|
||||
for (const nodeKey of dirtyLeaves) {
|
||||
const node = nodeMap.get(nodeKey);
|
||||
if (node !== undefined && !node.isAttached()) {
|
||||
if (!prevNodeMap.has(nodeKey)) {
|
||||
dirtyLeaves.delete(nodeKey);
|
||||
}
|
||||
nodeMap.delete(nodeKey);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user