|
@@ -8,6 +8,7 @@ import type {
|
|
ExcalidrawTextElement,
|
|
ExcalidrawTextElement,
|
|
FixedPointBinding,
|
|
FixedPointBinding,
|
|
FontFamilyValues,
|
|
FontFamilyValues,
|
|
|
|
+ NonDeletedSceneElementsMap,
|
|
OrderedExcalidrawElement,
|
|
OrderedExcalidrawElement,
|
|
PointBinding,
|
|
PointBinding,
|
|
StrokeRoundness,
|
|
StrokeRoundness,
|
|
@@ -60,6 +61,10 @@ import {
|
|
import type { LocalPoint, Radians } from "@excalidraw/math";
|
|
import type { LocalPoint, Radians } from "@excalidraw/math";
|
|
import { isFiniteNumber, pointFrom } from "@excalidraw/math";
|
|
import { isFiniteNumber, pointFrom } from "@excalidraw/math";
|
|
import { detectLineHeight } from "../element/textMeasurements";
|
|
import { detectLineHeight } from "../element/textMeasurements";
|
|
|
|
+import {
|
|
|
|
+ updateElbowArrowPoints,
|
|
|
|
+ validateElbowPoints,
|
|
|
|
+} from "../element/elbowArrow";
|
|
|
|
|
|
type RestoredAppState = Omit<
|
|
type RestoredAppState = Omit<
|
|
AppState,
|
|
AppState,
|
|
@@ -206,24 +211,6 @@ const restoreElementWithProperties = <
|
|
"customData" in extra ? extra.customData : element.customData;
|
|
"customData" in extra ? extra.customData : element.customData;
|
|
}
|
|
}
|
|
|
|
|
|
- // NOTE (mtolmacs): This is a temporary check to detect extremely large
|
|
|
|
- // element position or sizing
|
|
|
|
- if (
|
|
|
|
- element.x < -1e6 ||
|
|
|
|
- element.x > 1e6 ||
|
|
|
|
- element.y < -1e6 ||
|
|
|
|
- element.y > 1e6 ||
|
|
|
|
- element.width < -1e6 ||
|
|
|
|
- element.width > 1e6 ||
|
|
|
|
- element.height < -1e6 ||
|
|
|
|
- element.height > 1e6
|
|
|
|
- ) {
|
|
|
|
- console.error(
|
|
|
|
- "Restore element with properties size or position is too large",
|
|
|
|
- { element },
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return {
|
|
return {
|
|
// spread the original element properties to not lose unknown ones
|
|
// spread the original element properties to not lose unknown ones
|
|
// for forward-compatibility
|
|
// for forward-compatibility
|
|
@@ -240,21 +227,6 @@ const restoreElement = (
|
|
): typeof element | null => {
|
|
): typeof element | null => {
|
|
element = { ...element };
|
|
element = { ...element };
|
|
|
|
|
|
- // NOTE (mtolmacs): This is a temporary check to detect extremely large
|
|
|
|
- // element position or sizing
|
|
|
|
- if (
|
|
|
|
- element.x < -1e6 ||
|
|
|
|
- element.x > 1e6 ||
|
|
|
|
- element.y < -1e6 ||
|
|
|
|
- element.y > 1e6 ||
|
|
|
|
- element.width < -1e6 ||
|
|
|
|
- element.width > 1e6 ||
|
|
|
|
- element.height < -1e6 ||
|
|
|
|
- element.height > 1e6
|
|
|
|
- ) {
|
|
|
|
- console.error("Restore element size or position is too large", { element });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
switch (element.type) {
|
|
switch (element.type) {
|
|
case "text":
|
|
case "text":
|
|
// temp fix: cleanup legacy obsidian-excalidraw attribute else it'll
|
|
// temp fix: cleanup legacy obsidian-excalidraw attribute else it'll
|
|
@@ -596,7 +568,73 @@ export const restoreElements = (
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return restoredElements;
|
|
|
|
|
|
+ // NOTE (mtolmacs): Temporary fix for extremely large arrows
|
|
|
|
+ // Need to iterate again so we have attached text nodes in elementsMap
|
|
|
|
+ return restoredElements.map((element) => {
|
|
|
|
+ if (
|
|
|
|
+ isElbowArrow(element) &&
|
|
|
|
+ element.startBinding == null &&
|
|
|
|
+ element.endBinding == null &&
|
|
|
|
+ !validateElbowPoints(element.points)
|
|
|
|
+ ) {
|
|
|
|
+ return {
|
|
|
|
+ ...element,
|
|
|
|
+ ...updateElbowArrowPoints(
|
|
|
|
+ element,
|
|
|
|
+ restoredElementsMap as NonDeletedSceneElementsMap,
|
|
|
|
+ {
|
|
|
|
+ points: [
|
|
|
|
+ pointFrom<LocalPoint>(0, 0),
|
|
|
|
+ element.points[element.points.length - 1],
|
|
|
|
+ ],
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
|
|
+ index: element.index,
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ isElbowArrow(element) &&
|
|
|
|
+ element.startBinding &&
|
|
|
|
+ element.endBinding &&
|
|
|
|
+ element.startBinding.elementId === element.endBinding.elementId &&
|
|
|
|
+ element.points.length > 1 &&
|
|
|
|
+ element.points.some(
|
|
|
|
+ ([rx, ry]) => Math.abs(rx) > 1e6 || Math.abs(ry) > 1e6,
|
|
|
|
+ )
|
|
|
|
+ ) {
|
|
|
|
+ console.error("Fixing self-bound elbow arrow", element.id);
|
|
|
|
+ const boundElement = restoredElementsMap.get(
|
|
|
|
+ element.startBinding.elementId,
|
|
|
|
+ );
|
|
|
|
+ if (!boundElement) {
|
|
|
|
+ console.error(
|
|
|
|
+ "Bound element not found",
|
|
|
|
+ element.startBinding.elementId,
|
|
|
|
+ );
|
|
|
|
+ return element;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ ...element,
|
|
|
|
+ x: boundElement.x + boundElement.width / 2,
|
|
|
|
+ y: boundElement.y - 5,
|
|
|
|
+ width: boundElement.width,
|
|
|
|
+ height: boundElement.height,
|
|
|
|
+ points: [
|
|
|
|
+ pointFrom<LocalPoint>(0, 0),
|
|
|
|
+ pointFrom<LocalPoint>(0, -10),
|
|
|
|
+ pointFrom<LocalPoint>(boundElement.width / 2 + 5, -10),
|
|
|
|
+ pointFrom<LocalPoint>(
|
|
|
|
+ boundElement.width / 2 + 5,
|
|
|
|
+ boundElement.height / 2 + 5,
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return element;
|
|
|
|
+ });
|
|
};
|
|
};
|
|
|
|
|
|
const coalesceAppStateValue = <
|
|
const coalesceAppStateValue = <
|