mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-04-14 16:40:58 -04:00
fix single text element, unique id and tests
This commit is contained in:
parent
6c41e507db
commit
1c291f8b3d
4 changed files with 60 additions and 23 deletions
|
@ -135,23 +135,20 @@ export const loadSceneOrLibraryFromBlob = async (
|
|||
try {
|
||||
const data = JSON.parse(contents);
|
||||
if (isValidExcalidrawData(data)) {
|
||||
const excaldrawElements = convertToExcalidrawElements(
|
||||
data.elements || [],
|
||||
);
|
||||
return {
|
||||
type: MIME_TYPES.excalidraw,
|
||||
data: restore(
|
||||
{
|
||||
elements: clearElementsForExport(
|
||||
convertToExcalidrawElements(data.elements || []),
|
||||
),
|
||||
elements: clearElementsForExport(excaldrawElements),
|
||||
appState: {
|
||||
theme: localAppState?.theme,
|
||||
fileHandle: fileHandle || blob.handle || null,
|
||||
...cleanAppStateForExport(data.appState || {}),
|
||||
...(localAppState
|
||||
? calculateScrollCenter(
|
||||
convertToExcalidrawElements(data.elements || []),
|
||||
localAppState,
|
||||
null,
|
||||
)
|
||||
? calculateScrollCenter(excaldrawElements, localAppState, null)
|
||||
: {}),
|
||||
},
|
||||
files: data.files,
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { TEXT_ALIGN, VERTICAL_ALIGN } from "../constants";
|
||||
import {
|
||||
DEFAULT_FONT_FAMILY,
|
||||
DEFAULT_FONT_SIZE,
|
||||
TEXT_ALIGN,
|
||||
VERTICAL_ALIGN,
|
||||
} from "../constants";
|
||||
import {
|
||||
newElement,
|
||||
newLinearElement,
|
||||
|
@ -6,8 +11,17 @@ import {
|
|||
} from "../element";
|
||||
import { bindLinearElement } from "../element/binding";
|
||||
import { mutateElement } from "../element/mutateElement";
|
||||
import { ElementConstructorOpts, newTextElement } from "../element/newElement";
|
||||
import { VALID_CONTAINER_TYPES } from "../element/textElement";
|
||||
import {
|
||||
ElementConstructorOpts,
|
||||
newTextElement,
|
||||
regenerateId,
|
||||
} from "../element/newElement";
|
||||
import {
|
||||
VALID_CONTAINER_TYPES,
|
||||
getDefaultLineHeight,
|
||||
measureText,
|
||||
normalizeText,
|
||||
} from "../element/textElement";
|
||||
import {
|
||||
ExcalidrawBindableElement,
|
||||
ExcalidrawElement,
|
||||
|
@ -18,8 +32,8 @@ import {
|
|||
TextAlign,
|
||||
VerticalAlign,
|
||||
} from "../element/types";
|
||||
import { randomId } from "../random";
|
||||
import { MarkOptional } from "../utility-types";
|
||||
import { getFontString } from "../utils";
|
||||
import { ImportedDataState } from "./types";
|
||||
|
||||
export const ELEMENTS_SUPPORTING_PROGRAMMATIC_API = [
|
||||
|
@ -212,14 +226,20 @@ const excalidrawElements = (() => {
|
|||
};
|
||||
const clear = () => {
|
||||
res.length = 0;
|
||||
elementMap.clear();
|
||||
};
|
||||
const get = () => {
|
||||
return res;
|
||||
};
|
||||
const hasElementWithId = (id: string) => {
|
||||
const index = elementMap.get(id);
|
||||
return index !== undefined && index >= 0;
|
||||
};
|
||||
return {
|
||||
push,
|
||||
clear,
|
||||
get,
|
||||
hasElementWithId,
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -234,6 +254,15 @@ export const convertToExcalidrawElements = (
|
|||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
let elementId = element.id || regenerateId(null);
|
||||
|
||||
// To make sure every element has a unique id
|
||||
while (excalidrawElements.hasElementWithId(elementId)) {
|
||||
elementId = regenerateId(elementId);
|
||||
}
|
||||
const elementWithid = { ...element, id: elementId };
|
||||
|
||||
if (!ELEMENTS_SUPPORTING_PROGRAMMATIC_API.includes(element.type)) {
|
||||
excalidrawElements.push(element as ExcalidrawElement);
|
||||
|
||||
|
@ -242,7 +271,7 @@ export const convertToExcalidrawElements = (
|
|||
//@ts-ignore
|
||||
if (VALID_CONTAINER_TYPES.has(element.type) && element?.label?.text) {
|
||||
//@ts-ignore
|
||||
let [container, text] = bindTextToContainer(element, element.label);
|
||||
let [container, text] = bindTextToContainer(elementWithid, element.label);
|
||||
excalidrawElements.push(container);
|
||||
excalidrawElements.push(text);
|
||||
|
||||
|
@ -263,15 +292,28 @@ export const convertToExcalidrawElements = (
|
|||
} else {
|
||||
let excalidrawElement;
|
||||
if (element.type === "text") {
|
||||
excalidrawElement = newTextElement({
|
||||
...element,
|
||||
});
|
||||
const fontFamily = element?.fontFamily || DEFAULT_FONT_FAMILY;
|
||||
const fontSize = element?.fontSize || DEFAULT_FONT_SIZE;
|
||||
const lineHeight =
|
||||
element?.lineHeight || getDefaultLineHeight(fontFamily);
|
||||
const text = element.text ?? "";
|
||||
const normalizedText = normalizeText(text);
|
||||
const metrics = measureText(
|
||||
normalizedText,
|
||||
getFontString({ fontFamily, fontSize }),
|
||||
lineHeight,
|
||||
);
|
||||
excalidrawElement = {
|
||||
width: metrics.width,
|
||||
height: metrics.height,
|
||||
...elementWithid,
|
||||
};
|
||||
|
||||
excalidrawElements.push(excalidrawElement);
|
||||
excalidrawElements.push(excalidrawElement as ExcalidrawTextElement);
|
||||
} else if (element.type === "arrow" || element.type === "line") {
|
||||
const { linearElement, startBoundElement, endBoundElement } =
|
||||
//@ts-ignore
|
||||
bindLinearElementToElement(element);
|
||||
bindLinearElementToElement(elementWithid);
|
||||
excalidrawElements.push(linearElement);
|
||||
excalidrawElements.push(startBoundElement);
|
||||
excalidrawElements.push(endBoundElement);
|
||||
|
@ -287,8 +329,7 @@ export const convertToExcalidrawElements = (
|
|||
}
|
||||
} else {
|
||||
excalidrawElement = {
|
||||
...element,
|
||||
id: element.id || randomId(),
|
||||
...elementWithid,
|
||||
width:
|
||||
element?.width ||
|
||||
(ELEMENTS_SUPPORTING_PROGRAMMATIC_API.includes(element.type)
|
||||
|
|
|
@ -18,7 +18,6 @@ import type { cleanAppStateForExport } from "../appState";
|
|||
import { VERSIONS } from "../constants";
|
||||
import { MarkOptional } from "../utility-types";
|
||||
import { ElementConstructorOpts } from "../element/newElement";
|
||||
import { ELEMENTS_SUPPORTING_PROGRAMMATIC_API } from "./transform";
|
||||
|
||||
export interface ExportedDataState {
|
||||
type: string;
|
||||
|
@ -62,7 +61,7 @@ export interface ImportedDataState {
|
|||
type: "text";
|
||||
text: string;
|
||||
id?: ExcalidrawTextElement["id"];
|
||||
} & ElementConstructorOpts)
|
||||
} & Partial<ExcalidrawTextElement>)
|
||||
| ({
|
||||
type: ExcalidrawLinearElement["type"];
|
||||
x: number;
|
||||
|
|
|
@ -471,7 +471,7 @@ export const deepCopyElement = <T extends ExcalidrawElement>(
|
|||
* utility wrapper to generate new id. In test env it reuses the old + postfix
|
||||
* for test assertions.
|
||||
*/
|
||||
const regenerateId = (
|
||||
export const regenerateId = (
|
||||
/** supply null if no previous id exists */
|
||||
previousId: string | null,
|
||||
) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue