use elementsMap instead of array when passing to restoreElement

This commit is contained in:
dwelle
2025-11-13 16:37:51 +01:00
parent ee33204ed1
commit 46d79a6ec6

View File

@@ -55,6 +55,7 @@ import { isInvisiblySmallElement } from "@excalidraw/element";
import type { LocalPoint, Radians } from "@excalidraw/math"; import type { LocalPoint, Radians } from "@excalidraw/math";
import type { import type {
ElementsMap,
ExcalidrawArrowElement, ExcalidrawArrowElement,
ExcalidrawBindableElement, ExcalidrawBindableElement,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
@@ -128,7 +129,7 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {
const repairBinding = <T extends ExcalidrawArrowElement>( const repairBinding = <T extends ExcalidrawArrowElement>(
element: T, element: T,
binding: FixedPointBinding | null, binding: FixedPointBinding | null,
elements: readonly ExcalidrawElement[], elementsMap: Readonly<ElementsMap>,
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
): FixedPointBinding | null => { ): FixedPointBinding | null => {
if (!binding) { if (!binding) {
@@ -148,19 +149,17 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
} }
const boundElement = const boundElement =
(elements.find( (elementsMap.get(binding.elementId) as ExcalidrawBindableElement) ||
(el) => el.id === binding.elementId, undefined;
) as ExcalidrawBindableElement) || undefined;
if (boundElement) { if (boundElement) {
if (binding.mode) { if (binding.mode) {
return { return {
elementId: binding.elementId, elementId: binding.elementId,
mode: binding.mode || "orbit", mode: binding.mode || "orbit",
fixedPoint: normalizeFixedPoint(binding.fixedPoint || [0.51, 0.51]), fixedPoint: normalizeFixedPoint(binding.fixedPoint || [0.5, 0.5]),
} as FixedPointBinding | null; } as FixedPointBinding | null;
} }
const elementsMap = arrayToMap(elements);
const p = LinearElementEditor.getPointAtIndexGlobalCoordinates( const p = LinearElementEditor.getPointAtIndexGlobalCoordinates(
element, element,
startOrEnd === "start" ? 0 : element.points.length - 1, startOrEnd === "start" ? 0 : element.points.length - 1,
@@ -285,7 +284,7 @@ const restoreElementWithProperties = <
export const restoreElement = ( export const restoreElement = (
element: Exclude<ExcalidrawElement, ExcalidrawSelectionElement>, element: Exclude<ExcalidrawElement, ExcalidrawSelectionElement>,
elements: readonly ExcalidrawElement[], elementsMap: Readonly<ElementsMap>,
opts?: { opts?: {
deleteInvisibleElements?: boolean; deleteInvisibleElements?: boolean;
}, },
@@ -411,13 +410,13 @@ export const restoreElement = (
startBinding: repairBinding( startBinding: repairBinding(
element as ExcalidrawArrowElement, element as ExcalidrawArrowElement,
element.startBinding, element.startBinding,
elements, elementsMap,
"start", "start",
), ),
endBinding: repairBinding( endBinding: repairBinding(
element as ExcalidrawArrowElement, element as ExcalidrawArrowElement,
element.endBinding, element.endBinding,
elements, elementsMap,
"end", "end",
), ),
startArrowhead, startArrowhead,
@@ -572,7 +571,7 @@ const repairFrameMembership = (
}; };
export const restoreElements = ( export const restoreElements = (
elements: ImportedDataState["elements"], targetElements: ImportedDataState["elements"],
/** NOTE doesn't serve for reconciliation */ /** NOTE doesn't serve for reconciliation */
localElements: readonly ExcalidrawElement[] | null | undefined, localElements: readonly ExcalidrawElement[] | null | undefined,
opts?: opts?:
@@ -585,9 +584,10 @@ export const restoreElements = (
): OrderedExcalidrawElement[] => { ): OrderedExcalidrawElement[] => {
// used to detect duplicate top-level element ids // used to detect duplicate top-level element ids
const existingIds = new Set<string>(); const existingIds = new Set<string>();
const elementsMap = arrayToMap(targetElements || []);
const localElementsMap = localElements ? arrayToMap(localElements) : null; const localElementsMap = localElements ? arrayToMap(localElements) : null;
const restoredElements = syncInvalidIndices( const restoredElements = syncInvalidIndices(
(elements || []).reduce((elements, element) => { (targetElements || []).reduce((elements, element) => {
// filtering out selection, which is legacy, no longer kept in elements, // filtering out selection, which is legacy, no longer kept in elements,
// and causing issues if retained // and causing issues if retained
if (element.type === "selection") { if (element.type === "selection") {
@@ -596,7 +596,7 @@ export const restoreElements = (
let migratedElement: ExcalidrawElement | null = restoreElement( let migratedElement: ExcalidrawElement | null = restoreElement(
element, element,
elements, elementsMap,
{ {
deleteInvisibleElements: opts?.deleteInvisibleElements, deleteInvisibleElements: opts?.deleteInvisibleElements,
}, },