fix: restore text dimensions (#5432)

* fix: restore text dimensions

* fix tests

* update readme & changelog

* reduce API surface area by always refreshing dimensions for full `restore()`
This commit is contained in:
David Luzar 2022-10-28 23:31:56 +02:00 committed by GitHub
parent 36bf17cf59
commit c8f6e3faa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 21 deletions

View file

@ -14,6 +14,7 @@ import {
getNonDeletedElements,
getNormalizedDimensions,
isInvisiblySmallElement,
refreshTextDimensions,
} from "../element";
import { isLinearElementType } from "../element/typeChecks";
import { randomId } from "../random";
@ -138,6 +139,7 @@ const restoreElementWithProperties = <
const restoreElement = (
element: Exclude<ExcalidrawElement, ExcalidrawSelectionElement>,
refreshDimensions = true,
): typeof element | null => {
switch (element.type) {
case "text":
@ -150,7 +152,7 @@ const restoreElement = (
fontSize = parseInt(fontPx, 10);
fontFamily = getFontFamilyByName(_fontFamily);
}
return restoreElementWithProperties(element, {
element = restoreElementWithProperties(element, {
fontSize,
fontFamily,
text: element.text ?? "",
@ -160,6 +162,11 @@ const restoreElement = (
containerId: element.containerId ?? null,
originalText: element.originalText || element.text,
});
if (refreshDimensions) {
element = { ...element, ...refreshTextDimensions(element) };
}
return element;
case "freedraw": {
return restoreElementWithProperties(element, {
points: element.points,
@ -232,13 +239,17 @@ export const restoreElements = (
elements: ImportedDataState["elements"],
/** NOTE doesn't serve for reconciliation */
localElements: readonly ExcalidrawElement[] | null | undefined,
refreshDimensions = true,
): ExcalidrawElement[] => {
const localElementsMap = localElements ? arrayToMap(localElements) : null;
return (elements || []).reduce((elements, element) => {
// filtering out selection, which is legacy, no longer kept in elements,
// and causing issues if retained
if (element.type !== "selection" && !isInvisiblySmallElement(element)) {
let migratedElement: ExcalidrawElement | null = restoreElement(element);
let migratedElement: ExcalidrawElement | null = restoreElement(
element,
refreshDimensions,
);
if (migratedElement) {
const localElement = localElementsMap?.get(element.id);
if (localElement && localElement.version > migratedElement.version) {
@ -376,7 +387,7 @@ export const restore = (
localElements: readonly ExcalidrawElement[] | null | undefined,
): RestoredDataState => {
return {
elements: restoreElements(data?.elements, localElements),
elements: restoreElements(data?.elements, localElements, true),
appState: restoreAppState(data?.appState, localAppState || null),
files: data?.files || {},
};