Browse Source

fix: wysiwyg blur-submit on mobile (#8075)

David Luzar 1 year ago
parent
commit
08b13f971d
1 changed files with 28 additions and 5 deletions
  1. 28 5
      packages/excalidraw/element/textWysiwyg.tsx

+ 28 - 5
packages/excalidraw/element/textWysiwyg.tsx

@@ -493,6 +493,11 @@ export const textWysiwyg = ({
   // so that we don't need to create separate a callback for event handlers
   // so that we don't need to create separate a callback for event handlers
   let submittedViaKeyboard = false;
   let submittedViaKeyboard = false;
   const handleSubmit = () => {
   const handleSubmit = () => {
+    // prevent double submit
+    if (isDestroyed) {
+      return;
+    }
+    isDestroyed = true;
     // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg
     // cleanup must be run before onSubmit otherwise when app blurs the wysiwyg
     // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the
     // it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the
     // wysiwyg on update
     // wysiwyg on update
@@ -546,10 +551,6 @@ export const textWysiwyg = ({
   };
   };
 
 
   const cleanup = () => {
   const cleanup = () => {
-    if (isDestroyed) {
-      return;
-    }
-    isDestroyed = true;
     // remove events to ensure they don't late-fire
     // remove events to ensure they don't late-fire
     editable.onblur = null;
     editable.onblur = null;
     editable.oninput = null;
     editable.oninput = null;
@@ -641,6 +642,22 @@ export const textWysiwyg = ({
       // handle edge-case where pointerup doesn't fire e.g. due to user
       // handle edge-case where pointerup doesn't fire e.g. due to user
       // alt-tabbing away
       // alt-tabbing away
       window.addEventListener("blur", handleSubmit);
       window.addEventListener("blur", handleSubmit);
+    } else if (
+      event.target instanceof HTMLElement &&
+      !event.target.contains(editable) &&
+      // Vitest simply ignores stopPropagation, capture-mode, or rAF
+      // so without introducing crazier hacks, nothing we can do
+      !isTestEnv()
+    ) {
+      // On mobile, blur event doesn't seem to always fire correctly,
+      // so we want to also submit on pointerdown outside the wysiwyg.
+      // Done in the next frame to prevent pointerdown from creating a new text
+      // immediately (if tools locked) so that users on mobile have chance
+      // to submit first (to hide virtual keyboard).
+      // Note: revisit if we want to differ this behavior on Desktop
+      requestAnimationFrame(() => {
+        handleSubmit();
+      });
     }
     }
   };
   };
 
 
@@ -678,7 +695,13 @@ export const textWysiwyg = ({
     window.addEventListener("resize", updateWysiwygStyle);
     window.addEventListener("resize", updateWysiwygStyle);
   }
   }
 
 
-  window.addEventListener("pointerdown", onPointerDown);
+  editable.onpointerdown = (event) => event.stopPropagation();
+
+  // rAF (+ capture to by doubly sure) so we don't catch te pointerdown that
+  // triggered the wysiwyg
+  requestAnimationFrame(() => {
+    window.addEventListener("pointerdown", onPointerDown, { capture: true });
+  });
   window.addEventListener("wheel", stopEvent, {
   window.addEventListener("wheel", stopEvent, {
     passive: false,
     passive: false,
     capture: true,
     capture: true,