瀏覽代碼

Merge remote-tracking branch 'origin/master' into aakansha-no-trailing-space-render-text-container

Aakansha Doshi 2 年之前
父節點
當前提交
65e849804d
共有 3 個文件被更改,包括 40 次插入96 次删除
  1. 2 33
      src/element/newElement.ts
  2. 29 15
      src/element/textWysiwyg.test.tsx
  3. 9 48
      src/element/textWysiwyg.tsx

+ 2 - 33
src/element/newElement.ts

@@ -20,15 +20,13 @@ import {
   isTestEnv,
 } from "../utils";
 import { randomInteger, randomId } from "../random";
-import { bumpVersion, mutateElement, newElementWith } from "./mutateElement";
+import { bumpVersion, newElementWith } from "./mutateElement";
 import { getNewGroupIdsForDuplication } from "../groups";
 import { AppState } from "../types";
 import { getElementAbsoluteCoords } from ".";
 import { adjustXYWithRotation } from "../math";
 import { getResizedElementAbsoluteCoords } from "./bounds";
 import {
-  getBoundTextElementOffset,
-  getContainerDims,
   getContainerElement,
   measureText,
   normalizeText,
@@ -44,7 +42,6 @@ import {
   DEFAULT_VERTICAL_ALIGN,
   VERTICAL_ALIGN,
 } from "../constants";
-import { isArrowElement } from "./typeChecks";
 import { MarkOptional, Merge, Mutable } from "../utility-types";
 
 type ElementConstructorOpts = MarkOptional<
@@ -211,18 +208,11 @@ const getAdjustedDimensions = (
   height: number;
   baseline: number;
 } => {
-  const container = getContainerElement(element);
-
   const {
     width: nextWidth,
     height: nextHeight,
     baseline: nextBaseline,
-  } = measureText(
-    nextText,
-    getFontString(element),
-    element.lineHeight,
-    container ? getBoundTextMaxWidth(container) : null,
-  );
+  } = measureText(nextText, getFontString(element), element.lineHeight);
   const { textAlign, verticalAlign } = element;
   let x: number;
   let y: number;
@@ -273,27 +263,6 @@ const getAdjustedDimensions = (
     );
   }
 
-  // make sure container dimensions are set properly when
-  // text editor overflows beyond viewport dimensions
-  if (container) {
-    const boundTextElementPadding = getBoundTextElementOffset(element);
-
-    const containerDims = getContainerDims(container);
-    let height = containerDims.height;
-    let width = containerDims.width;
-    if (nextHeight > height - boundTextElementPadding * 2) {
-      height = nextHeight + boundTextElementPadding * 2;
-    }
-    if (nextWidth > width - boundTextElementPadding * 2) {
-      width = nextWidth + boundTextElementPadding * 2;
-    }
-    if (
-      !isArrowElement(container) &&
-      (height !== containerDims.height || width !== containerDims.width)
-    ) {
-      mutateElement(container, { height, width });
-    }
-  }
   return {
     width: nextWidth,
     height: nextHeight,

+ 29 - 15
src/element/textWysiwyg.test.tsx

@@ -1213,32 +1213,46 @@ describe("textWysiwyg", () => {
     });
 
     it("should restore original container height and clear cache once text is unbind", async () => {
-      const originalRectHeight = rectangle.height;
-      expect(rectangle.height).toBe(originalRectHeight);
+      const container = API.createElement({
+        type: "rectangle",
+        height: 75,
+        width: 90,
+      });
+      const originalRectHeight = container.height;
+      expect(container.height).toBe(originalRectHeight);
 
-      Keyboard.keyPress(KEYS.ENTER);
-      const editor = document.querySelector(
-        ".excalidraw-textEditorContainer > textarea",
-      ) as HTMLTextAreaElement;
-      await new Promise((r) => setTimeout(r, 0));
+      const text = API.createElement({
+        type: "text",
+        text: "Online whiteboard collaboration made easy",
+      });
+      h.elements = [container, text];
+      API.setSelectedElements([container, text]);
 
-      fireEvent.change(editor, {
-        target: { value: "Online whiteboard collaboration made easy" },
+      fireEvent.contextMenu(GlobalTestState.canvas, {
+        button: 2,
+        clientX: 20,
+        clientY: 30,
       });
-      editor.blur();
-      expect(rectangle.height).toBe(185);
-      mouse.select(rectangle);
+      let contextMenu = document.querySelector(".context-menu");
+
+      fireEvent.click(
+        queryByText(contextMenu as HTMLElement, "Bind text to the container")!,
+      );
+
+      expect((h.elements[1] as ExcalidrawTextElementWithContainer).text).toBe(
+        "Online \nwhitebo\nard \ncollabo\nration \nmade \neasy",
+      );
       fireEvent.contextMenu(GlobalTestState.canvas, {
         button: 2,
         clientX: 20,
         clientY: 30,
       });
-      const contextMenu = document.querySelector(".context-menu");
+      contextMenu = document.querySelector(".context-menu");
       fireEvent.click(queryByText(contextMenu as HTMLElement, "Unbind text")!);
       expect(h.elements[0].boundElements).toEqual([]);
-      expect(getOriginalContainerHeightFromCache(rectangle.id)).toBe(null);
+      expect(getOriginalContainerHeightFromCache(container.id)).toBe(null);
 
-      expect(rectangle.height).toBe(originalRectHeight);
+      expect(container.height).toBe(originalRectHeight);
     });
 
     it("should reset the container height cache when resizing", async () => {

+ 9 - 48
src/element/textWysiwyg.tsx

@@ -11,7 +11,7 @@ import {
   isBoundToContainer,
   isTextElement,
 } from "./typeChecks";
-import { CLASSES, isSafari, VERTICAL_ALIGN } from "../constants";
+import { CLASSES, isSafari } from "../constants";
 import {
   ExcalidrawElement,
   ExcalidrawLinearElement,
@@ -23,7 +23,6 @@ import { AppState } from "../types";
 import { mutateElement } from "./mutateElement";
 import {
   getBoundTextElementId,
-  getContainerCoords,
   getContainerDims,
   getContainerElement,
   getTextElementAngle,
@@ -35,6 +34,7 @@ import {
   getBoundTextMaxWidth,
   computeContainerDimensionForBoundText,
   detectLineHeight,
+  computeBoundTextPosition,
 } from "./textElement";
 import {
   actionDecreaseFontSize,
@@ -161,7 +161,7 @@ export const textWysiwyg = ({
       let textElementWidth = updatedTextElement.width;
       // Set to element height by default since that's
       // what is going to be used for unbounded text
-      let textElementHeight = updatedTextElement.height;
+      const textElementHeight = updatedTextElement.height;
 
       if (container && updatedTextElement.containerId) {
         if (isArrowElement(container)) {
@@ -178,15 +178,6 @@ export const textWysiwyg = ({
           editable,
         );
         const containerDims = getContainerDims(container);
-        // using editor.style.height to get the accurate height of text editor
-        const editorHeight = Number(editable.style.height.slice(0, -2));
-        if (editorHeight > 0) {
-          textElementHeight = editorHeight;
-        }
-        if (propertiesUpdated) {
-          // update height of the editor after properties updated
-          textElementHeight = updatedTextElement.height;
-        }
 
         let originalContainerData;
         if (propertiesUpdated) {
@@ -231,22 +222,12 @@ export const textWysiwyg = ({
             container.type,
           );
           mutateElement(container, { height: targetContainerHeight });
-        }
-        // Start pushing text upward until a diff of 30px (padding)
-        // is reached
-        else {
-          const containerCoords = getContainerCoords(container);
-
-          // vertically center align the text
-          if (verticalAlign === VERTICAL_ALIGN.MIDDLE) {
-            if (!isArrowElement(container)) {
-              coordY =
-                containerCoords.y + maxHeight / 2 - textElementHeight / 2;
-            }
-          }
-          if (verticalAlign === VERTICAL_ALIGN.BOTTOM) {
-            coordY = containerCoords.y + (maxHeight - textElementHeight);
-          }
+        } else {
+          const { y } = computeBoundTextPosition(
+            container,
+            updatedTextElement as ExcalidrawTextElementWithContainer,
+          );
+          coordY = y;
         }
       }
       const [viewportX, viewportY] = getViewportCoords(coordX, coordY);
@@ -392,26 +373,6 @@ export const textWysiwyg = ({
     };
 
     editable.oninput = () => {
-      const updatedTextElement = Scene.getScene(element)?.getElement(
-        id,
-      ) as ExcalidrawTextElement;
-      const font = getFontString(updatedTextElement);
-      if (isBoundToContainer(element)) {
-        const container = getContainerElement(element);
-        const wrappedText = wrapText(
-          normalizeText(editable.value),
-          font,
-          getBoundTextMaxWidth(container!),
-        );
-        const { width, height } = measureText(
-          wrappedText,
-          font,
-          updatedTextElement.lineHeight,
-          getBoundTextMaxWidth(container!),
-        );
-        editable.style.width = `${width}px`;
-        editable.style.height = `${height}px`;
-      }
       onChange(normalizeText(editable.value));
     };
   }