Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/excalidraw/excalidraw
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelle committed Jun 22, 2023
2 parents e03b600 + b7350f9 commit 2581c86
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
22 changes: 22 additions & 0 deletions src/data/restore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,24 @@ const repairBoundElement = (
}
};

/**
* Remove an element's frameId if its containing frame is non-existent
*
* NOTE mutates elements.
*/
const repairFrameMembership = (
element: Mutable<ExcalidrawElement>,
elementsMap: Map<string, Mutable<ExcalidrawElement>>,
) => {
if (element.frameId) {
const containingFrame = elementsMap.get(element.frameId);

if (!containingFrame) {
element.frameId = null;
}
}
};

export const restoreElements = (
elements: ImportedDataState["elements"],
/** NOTE doesn't serve for reconciliation */
Expand Down Expand Up @@ -410,6 +428,10 @@ export const restoreElements = (
// repair binding. Mutates elements.
const restoredElementsMap = arrayToMap(restoredElements);
for (const element of restoredElements) {
if (element.frameId) {
repairFrameMembership(element, restoredElementsMap);
}

if (isTextElement(element) && element.containerId) {
repairBoundElement(element, restoredElementsMap);
} else if (element.boundElements) {
Expand Down
7 changes: 5 additions & 2 deletions src/frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export const groupsAreCompletelyOutOfFrame = (
/**
* Returns a map of frameId to frame elements. Includes empty frames.
*/
export const groupByFrames = (elements: ExcalidrawElementsIncludingDeleted) => {
export const groupByFrames = (elements: readonly ExcalidrawElement[]) => {
const frameElementsMap = new Map<
ExcalidrawElement["id"],
ExcalidrawElement[]
Expand Down Expand Up @@ -591,14 +591,17 @@ export const updateFrameMembershipOfSelectedElements = (

elementsToFilter.forEach((element) => {
if (
element.frameId &&
!isFrameElement(element) &&
!isElementInFrame(element, allElements, appState)
) {
elementsToRemove.add(element);
}
});

return removeElementsFromFrame(allElements, [...elementsToRemove], appState);
return elementsToRemove.size > 0
? removeElementsFromFrame(allElements, [...elementsToRemove], appState)
: allElements;
};

/**
Expand Down
15 changes: 14 additions & 1 deletion src/zindex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,22 @@ function shift(
) => ExcalidrawElement[] | readonly ExcalidrawElement[],
elementsToBeMoved?: readonly ExcalidrawElement[],
) {
let rootElements = elements.filter((element) => isRootElement(element));
const elementsMap = arrayToMap(elements);
const frameElementsMap = groupByFrames(elements);

// in case root is non-existent, we promote children elements to root
let rootElements = elements.filter(
(element) =>
isRootElement(element) ||
(element.frameId && !elementsMap.has(element.frameId)),
);
// and remove non-existet root
for (const frameId of frameElementsMap.keys()) {
if (!elementsMap.has(frameId)) {
frameElementsMap.delete(frameId);
}
}

// shift the root elements first
rootElements = shiftFunction(
rootElements,
Expand Down

0 comments on commit 2581c86

Please sign in to comment.