1
0
mirror of https://github.com/excalidraw/excalidraw.git synced 2024-11-10 11:35:52 +01:00

fix: call stack size exceeded when paste large text (#6373) (#6396)

* fix: call stack size exceeded when paste large text (#6373)

* fix: add test case for paste multi-line text

* fix

* tweak

* add missing assertion

* add comments

* lint

---------

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
This commit is contained in:
dongfang 2023-03-29 16:15:30 +08:00 committed by GitHub
parent 25bb6738ea
commit 44453b725d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 11 deletions

@ -526,6 +526,44 @@ describe("textWysiwyg", () => {
]); ]);
}); });
it("should compute the container height correctly and not throw error when height is updated while editing the text", async () => {
const diamond = API.createElement({
type: "diamond",
x: 10,
y: 20,
width: 90,
height: 75,
});
h.elements = [diamond];
expect(h.elements.length).toBe(1);
expect(h.elements[0].id).toBe(diamond.id);
API.setSelectedElements([diamond]);
Keyboard.keyPress(KEYS.ENTER);
const editor = document.querySelector(
".excalidraw-textEditorContainer > textarea",
) as HTMLTextAreaElement;
await new Promise((r) => setTimeout(r, 0));
const value = new Array(1000).fill("1").join("\n");
// Pasting large text to simulate height increase
expect(() =>
fireEvent.input(editor, { target: { value } }),
).not.toThrow();
expect(diamond.height).toBe(50020);
// Clearing text to simulate height decrease
expect(() =>
fireEvent.input(editor, { target: { value: "" } }),
).not.toThrow();
expect(diamond.height).toBe(70);
});
it("should bind text to container when double clicked on center of transparent container", async () => { it("should bind text to container when double clicked on center of transparent container", async () => {
const rectangle = API.createElement({ const rectangle = API.createElement({
type: "rectangle", type: "rectangle",
@ -1181,9 +1219,7 @@ describe("textWysiwyg", () => {
expect( expect(
(h.elements[1] as ExcalidrawTextElementWithContainer).fontSize, (h.elements[1] as ExcalidrawTextElementWithContainer).fontSize,
).toEqual(36); ).toEqual(36);
expect(getOriginalContainerHeightFromCache(rectangle.id)).toBe( expect(getOriginalContainerHeightFromCache(rectangle.id)).toBe(97);
96.39999999999999,
);
}); });
it("should update line height when font family updated", async () => { it("should update line height when font family updated", async () => {

@ -34,6 +34,7 @@ import {
wrapText, wrapText,
getMaxContainerHeight, getMaxContainerHeight,
getMaxContainerWidth, getMaxContainerWidth,
computeContainerDimensionForBoundText,
} from "./textElement"; } from "./textElement";
import { import {
actionDecreaseFontSize, actionDecreaseFontSize,
@ -208,11 +209,12 @@ export const textWysiwyg = ({
// autogrow container height if text exceeds // autogrow container height if text exceeds
if (!isArrowElement(container) && textElementHeight > maxHeight) { if (!isArrowElement(container) && textElementHeight > maxHeight) {
const diff = Math.min( const targetContainerHeight = computeContainerDimensionForBoundText(
textElementHeight - maxHeight, textElementHeight,
element.lineHeight, container.type,
); );
mutateElement(container, { height: containerDims.height + diff });
mutateElement(container, { height: targetContainerHeight });
return; return;
} else if ( } else if (
// autoshrink container height until original container height // autoshrink container height until original container height
@ -221,11 +223,11 @@ export const textWysiwyg = ({
containerDims.height > originalContainerData.height && containerDims.height > originalContainerData.height &&
textElementHeight < maxHeight textElementHeight < maxHeight
) { ) {
const diff = Math.min( const targetContainerHeight = computeContainerDimensionForBoundText(
maxHeight - textElementHeight, textElementHeight,
element.lineHeight, container.type,
); );
mutateElement(container, { height: containerDims.height - diff }); mutateElement(container, { height: targetContainerHeight });
} }
// Start pushing text upward until a diff of 30px (padding) // Start pushing text upward until a diff of 30px (padding)
// is reached // is reached