@inkandswitch/patchwork-pkg-base 0.0.23 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import {
2
2
  createTLStore,
3
3
  defaultShapeUtils,
4
4
  tldrawValueToAutomergeValue
5
- } from "./chunk-VF5CY24G.js";
5
+ } from "./chunk-GDYMD4VT.js";
6
6
  import "./chunk-IKZWERSR.js";
7
7
 
8
8
  // src/datatype.ts
@@ -30,7 +30,7 @@ import {
30
30
  useEditor,
31
31
  useValue,
32
32
  validation_exports
33
- } from "./chunk-VF5CY24G.js";
33
+ } from "./chunk-GDYMD4VT.js";
34
34
  import {
35
35
  __commonJS,
36
36
  __export,
@@ -7508,10 +7508,7 @@ var DiffShapeWrapper = (0, import_react5.forwardRef)(
7508
7508
 
7509
7509
  // src/PatchworkDocShape.tsx
7510
7510
  var import_react6 = __toESM(require_react(), 1);
7511
- import {
7512
- getRegistry,
7513
- getSupportedToolsForType
7514
- } from "@inkandswitch/patchwork-plugins";
7511
+ import { getSupportedToolsForType } from "@inkandswitch/patchwork-plugins";
7515
7512
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
7516
7513
  var import_react8 = (
7517
7514
  // @ts-expect-error Custom element from @inkandswitch/patchwork-elements
@@ -7586,69 +7583,24 @@ function getDefaultToolId(datatypeId) {
7586
7583
  return "";
7587
7584
  }
7588
7585
  }
7589
- function useSupportedTools(docType) {
7590
- return (0, import_react6.useMemo)(() => {
7591
- if (!docType) return [];
7592
- try {
7593
- return getSupportedToolsForType(docType).filter((t) => !t.unlisted);
7594
- } catch {
7595
- return [];
7596
- }
7597
- }, [docType]);
7598
- }
7599
7586
  function useIsImage(docUrl) {
7600
7587
  const [doc] = useDocument(
7601
7588
  docUrl ? docUrl : void 0
7602
7589
  );
7603
7590
  return doc?.["@patchwork"]?.type === "file" && !!doc?.mimeType?.startsWith("image/");
7604
7591
  }
7605
- function openDocumentInHost(el, url, toolId) {
7606
- el.dispatchEvent(
7607
- new CustomEvent("patchwork:open-document", {
7608
- detail: { url, toolId: toolId || void 0 },
7609
- composed: true,
7610
- bubbles: true
7611
- })
7612
- );
7613
- }
7614
7592
  function PatchworkDocComponent({ shape }) {
7615
- const { docUrl, docName, docType, toolId } = shape.props;
7593
+ const { docUrl, docName, toolId } = shape.props;
7616
7594
  const editor = useEditor();
7617
- const repo = useRepo();
7618
7595
  const isImage = useIsImage(docUrl);
7619
- const tools = useSupportedTools(docType);
7620
- const isSelectTool = useValue("is select tool", () => editor.getCurrentToolId() === "select", [
7621
- editor
7622
- ]);
7623
7596
  const isEditingShape = useValue(
7624
7597
  "is editing shape",
7625
7598
  () => editor.getEditingShapeId() === shape.id,
7626
7599
  [editor, shape.id]
7627
7600
  );
7628
7601
  const isFocused = isEditingShape;
7629
- const [isEditingName, setIsEditingName] = (0, import_react6.useState)(false);
7630
- const [toolMenuOpen, setToolMenuOpen] = (0, import_react6.useState)(false);
7631
- const nameInputRef = (0, import_react6.useRef)(null);
7632
7602
  const containerRef = (0, import_react6.useRef)(null);
7633
7603
  const contentRef = (0, import_react6.useRef)(null);
7634
- const toolMenuRef = (0, import_react6.useRef)(null);
7635
- const currentTool = tools.find((t) => t.id === toolId) ?? tools[0];
7636
- (0, import_react6.useEffect)(() => {
7637
- if (isEditingName && nameInputRef.current) {
7638
- nameInputRef.current.focus();
7639
- nameInputRef.current.select();
7640
- }
7641
- }, [isEditingName]);
7642
- (0, import_react6.useEffect)(() => {
7643
- if (!toolMenuOpen) return;
7644
- const handler = (e) => {
7645
- if (toolMenuRef.current && !toolMenuRef.current.contains(e.target)) {
7646
- setToolMenuOpen(false);
7647
- }
7648
- };
7649
- window.addEventListener("pointerdown", handler, true);
7650
- return () => window.removeEventListener("pointerdown", handler, true);
7651
- }, [toolMenuOpen]);
7652
7604
  (0, import_react6.useEffect)(() => {
7653
7605
  if (!isFocused) return;
7654
7606
  const el = contentRef.current;
@@ -7675,58 +7627,23 @@ function PatchworkDocComponent({ shape }) {
7675
7627
  el.removeEventListener("pointerup", stopPointer, true);
7676
7628
  };
7677
7629
  }, [isFocused]);
7678
- const handleToolChange = (0, import_react6.useCallback)(
7679
- (newToolId) => {
7630
+ (0, import_react6.useEffect)(() => {
7631
+ const el = containerRef.current;
7632
+ if (!el) return;
7633
+ const onToolChanged = (e) => {
7634
+ e.stopPropagation();
7635
+ const newToolId = e.detail?.toolId;
7636
+ if (!newToolId) return;
7680
7637
  editor.updateShape({
7681
7638
  id: shape.id,
7682
7639
  type: PATCHWORK_DOC_SHAPE_TYPE,
7683
7640
  props: { toolId: newToolId }
7684
7641
  });
7685
- setToolMenuOpen(false);
7686
- },
7687
- [editor, shape.id]
7688
- );
7689
- const handleOpenDocument = (0, import_react6.useCallback)(() => {
7690
- const el = containerRef.current;
7691
- if (!el || !docUrl) return;
7692
- openDocumentInHost(el, docUrl, toolId || void 0);
7693
- }, [docUrl, toolId]);
7694
- const handleRename = (0, import_react6.useCallback)(
7695
- async (newName) => {
7696
- const trimmed = newName.trim();
7697
- if (!trimmed || trimmed === docName || !docUrl || !docType) {
7698
- setIsEditingName(false);
7699
- return;
7700
- }
7701
- try {
7702
- const datatype = await loadDatatype(docType);
7703
- if (datatype?.module.setTitle) {
7704
- const childHandle = await repo.find(docUrl);
7705
- childHandle.change((d) => {
7706
- datatype.module.setTitle(d, trimmed);
7707
- });
7708
- const childDoc = childHandle.doc();
7709
- const canonicalName = childDoc ? datatype.module.getTitle(childDoc) : trimmed;
7710
- editor.updateShape({
7711
- id: shape.id,
7712
- type: PATCHWORK_DOC_SHAPE_TYPE,
7713
- props: { docName: canonicalName }
7714
- });
7715
- } else {
7716
- editor.updateShape({
7717
- id: shape.id,
7718
- type: PATCHWORK_DOC_SHAPE_TYPE,
7719
- props: { docName: trimmed }
7720
- });
7721
- }
7722
- } catch (err) {
7723
- console.warn("[tldraw4] rename failed", err);
7724
- }
7725
- setIsEditingName(false);
7726
- },
7727
- [editor, shape.id, docName, docUrl, docType, repo]
7728
- );
7729
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(HTMLContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
7642
+ };
7643
+ el.addEventListener("patchwork:embed-tool-changed", onToolChanged);
7644
+ return () => el.removeEventListener("patchwork:embed-tool-changed", onToolChanged);
7645
+ }, [editor, shape.id]);
7646
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(HTMLContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7730
7647
  "div",
7731
7648
  {
7732
7649
  ref: containerRef,
@@ -7742,288 +7659,61 @@ function PatchworkDocComponent({ shape }) {
7742
7659
  boxShadow: "0 1px 4px rgba(0,0,0,0.10)",
7743
7660
  pointerEvents: "all"
7744
7661
  },
7745
- children: [
7746
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
7747
- "div",
7748
- {
7749
- onPointerDown: () => {
7750
- if (isEditingShape) editor.setEditingShape(null);
7751
- },
7752
- style: {
7753
- display: "flex",
7754
- alignItems: "center",
7755
- gap: "6px",
7756
- height: "30px",
7757
- padding: "0 6px",
7758
- borderBottom: "1px solid var(--color-divider, #e5e7eb)",
7759
- flexShrink: 0,
7760
- cursor: "grab",
7761
- userSelect: "none",
7762
- background: "var(--color-low, #fafafa)"
7763
- },
7764
- children: [
7765
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7766
- "button",
7767
- {
7768
- type: "button",
7769
- title: "Open document",
7770
- onClick: (e) => {
7771
- e.stopPropagation();
7772
- handleOpenDocument();
7773
- },
7774
- onPointerDown: (e) => e.stopPropagation(),
7775
- style: {
7776
- display: "inline-flex",
7777
- alignItems: "center",
7778
- justifyContent: "center",
7779
- width: "20px",
7780
- height: "20px",
7781
- border: "none",
7782
- borderRadius: "4px",
7783
- background: "transparent",
7784
- cursor: "pointer",
7785
- color: "var(--color-text, #374151)",
7786
- flexShrink: 0
7787
- },
7788
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7789
- "path",
7790
- {
7791
- d: "M6 3H3.5A1.5 1.5 0 0 0 2 4.5v8A1.5 1.5 0 0 0 3.5 14h8a1.5 1.5 0 0 0 1.5-1.5V10M9 3h4v4M13 3 7 9",
7792
- stroke: "currentColor",
7793
- strokeWidth: "1.4",
7794
- strokeLinecap: "round",
7795
- strokeLinejoin: "round"
7796
- }
7797
- ) })
7798
- }
7799
- ),
7800
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: isEditingName ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7801
- "input",
7802
- {
7803
- ref: nameInputRef,
7804
- defaultValue: docName,
7805
- onPointerDown: (e) => e.stopPropagation(),
7806
- onClick: (e) => e.stopPropagation(),
7807
- onKeyDown: (e) => {
7808
- e.stopPropagation();
7809
- if (e.key === "Enter") handleRename(e.target.value);
7810
- if (e.key === "Escape") setIsEditingName(false);
7811
- },
7812
- onBlur: (e) => handleRename(e.target.value),
7813
- style: {
7814
- width: "100%",
7815
- fontSize: "13px",
7816
- fontWeight: 600,
7817
- fontFamily: "inherit",
7818
- color: "var(--color-text, #111827)",
7819
- background: "var(--color-panel, #fff)",
7820
- border: "1px solid var(--color-selected, #2f80ed)",
7821
- borderRadius: "4px",
7822
- padding: "1px 4px",
7823
- outline: "none",
7824
- boxSizing: "border-box"
7825
- }
7826
- }
7827
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7828
- "span",
7829
- {
7830
- onPointerDown: (e) => {
7831
- e.stopPropagation();
7832
- },
7833
- onClick: (e) => {
7834
- e.stopPropagation();
7835
- setIsEditingName(true);
7836
- },
7837
- title: docName,
7838
- style: {
7839
- display: "block",
7840
- fontSize: "13px",
7841
- fontWeight: 600,
7842
- color: "var(--color-text, #111827)",
7843
- overflow: "hidden",
7844
- textOverflow: "ellipsis",
7845
- whiteSpace: "nowrap",
7846
- cursor: "text"
7847
- },
7848
- children: docName || "Untitled"
7849
- }
7850
- ) }),
7851
- currentTool && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: toolMenuRef, style: { position: "relative", flexShrink: 0 }, children: [
7852
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
7853
- "button",
7854
- {
7855
- type: "button",
7856
- title: "Choose view",
7857
- onClick: (e) => {
7858
- e.stopPropagation();
7859
- if (tools.length > 1) setToolMenuOpen((v) => !v);
7860
- },
7861
- onPointerDown: (e) => e.stopPropagation(),
7862
- style: {
7863
- display: "inline-flex",
7864
- alignItems: "center",
7865
- gap: "4px",
7866
- maxWidth: "140px",
7867
- padding: "2px 8px",
7868
- border: "1px solid var(--color-divider, #e5e7eb)",
7869
- borderRadius: "9999px",
7870
- background: "var(--color-panel, #fff)",
7871
- cursor: tools.length > 1 ? "pointer" : "default",
7872
- fontSize: "11px",
7873
- fontWeight: 500,
7874
- color: "var(--color-text-1, #4b5563)",
7875
- whiteSpace: "nowrap"
7876
- },
7877
- children: [
7878
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7879
- "span",
7880
- {
7881
- style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
7882
- children: currentTool.name
7883
- }
7884
- ),
7885
- tools.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "8", height: "8", viewBox: "0 0 8 8", style: { opacity: 0.6 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7886
- "path",
7887
- {
7888
- d: "M1 2.5 4 5.5 7 2.5",
7889
- stroke: "currentColor",
7890
- strokeWidth: "1.5",
7891
- fill: "none",
7892
- strokeLinecap: "round",
7893
- strokeLinejoin: "round"
7894
- }
7895
- ) })
7896
- ]
7897
- }
7898
- ),
7899
- toolMenuOpen && tools.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7900
- "div",
7901
- {
7902
- onPointerDown: (e) => e.stopPropagation(),
7903
- style: {
7904
- position: "absolute",
7905
- top: "100%",
7906
- right: 0,
7907
- marginTop: "4px",
7908
- background: "var(--color-panel, #fff)",
7909
- border: "1px solid var(--color-divider, #e5e7eb)",
7910
- borderRadius: "6px",
7911
- boxShadow: "0 4px 12px rgba(0,0,0,0.12)",
7912
- padding: "4px",
7913
- minWidth: "140px",
7914
- zIndex: 1e4
7915
- },
7916
- children: tools.map((t) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7917
- "button",
7918
- {
7919
- type: "button",
7920
- onPointerDown: (e) => {
7921
- e.stopPropagation();
7922
- e.preventDefault();
7923
- handleToolChange(t.id);
7924
- },
7925
- style: {
7926
- display: "block",
7927
- width: "100%",
7928
- padding: "5px 10px",
7929
- border: "none",
7930
- borderRadius: "4px",
7931
- background: t.id === currentTool.id ? "var(--color-selected, #e8f0fe)" : "transparent",
7932
- cursor: "pointer",
7933
- fontSize: "12px",
7934
- color: "var(--color-text, #374151)",
7935
- textAlign: "left",
7936
- whiteSpace: "nowrap"
7937
- },
7938
- children: t.name
7939
- },
7940
- t.id
7941
- ))
7942
- }
7943
- )
7944
- ] })
7945
- ]
7946
- }
7947
- ),
7948
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7949
- "div",
7950
- {
7951
- ref: contentRef,
7952
- style: {
7953
- flex: 1,
7954
- minHeight: 0,
7955
- overflow: "hidden",
7956
- position: "relative",
7957
- pointerEvents: isSelectTool ? "auto" : "none",
7958
- userSelect: isFocused ? "text" : "none",
7959
- cursor: isFocused ? "auto" : void 0
7960
- },
7961
- onPointerDown: isSelectTool ? (e) => {
7962
- e.stopPropagation();
7963
- if (!isEditingShape) editor.setEditingShape(shape.id);
7964
- } : void 0,
7965
- onPointerUp: isSelectTool ? (e) => {
7966
- e.stopPropagation();
7967
- e.target?.dispatchEvent(
7968
- new MouseEvent("click", {
7969
- bubbles: true,
7970
- cancelable: true,
7971
- view: window,
7972
- clientX: e.clientX,
7973
- clientY: e.clientY
7974
- })
7975
- );
7976
- } : void 0,
7977
- children: docUrl && isImage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7978
- "img",
7979
- {
7980
- src: automergeUrlToServiceWorkerUrl(docUrl),
7981
- alt: docName,
7982
- style: { width: "100%", height: "100%", objectFit: "contain" }
7983
- }
7984
- ) : docUrl ? /* @__PURE__ */ (0, import_react8.createElement)(
7985
- "patchwork-view",
7986
- {
7987
- "doc-url": docUrl,
7988
- ...toolId ? { "tool-id": toolId } : {},
7989
- key: toolId || "default",
7990
- style: { display: "block", width: "100%", height: "100%" }
7991
- }
7992
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7993
- "div",
7994
- {
7995
- style: {
7996
- display: "flex",
7997
- alignItems: "center",
7998
- justifyContent: "center",
7999
- height: "100%",
8000
- color: "var(--color-text-3, #9ca3af)",
8001
- fontSize: "12px"
8002
- },
8003
- children: "No document"
8004
- }
8005
- )
8006
- }
8007
- )
8008
- ]
7662
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7663
+ "div",
7664
+ {
7665
+ ref: contentRef,
7666
+ style: {
7667
+ flex: 1,
7668
+ minHeight: 0,
7669
+ overflow: "hidden",
7670
+ position: "relative",
7671
+ pointerEvents: isFocused ? "auto" : "none",
7672
+ userSelect: isFocused ? "text" : "none",
7673
+ cursor: isFocused ? "auto" : void 0
7674
+ },
7675
+ children: docUrl && isImage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7676
+ "img",
7677
+ {
7678
+ src: automergeUrlToServiceWorkerUrl(docUrl),
7679
+ alt: docName,
7680
+ style: { width: "100%", height: "100%", objectFit: "contain" }
7681
+ }
7682
+ ) : docUrl ? /* @__PURE__ */ (0, import_react8.createElement)(
7683
+ "patchwork-view",
7684
+ {
7685
+ "doc-url": docUrl,
7686
+ "tool-id": "embed",
7687
+ ...toolId ? { "embed-tool-id": toolId } : {},
7688
+ key: toolId || "default",
7689
+ style: { display: "block", width: "100%", height: "100%" }
7690
+ }
7691
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
7692
+ "div",
7693
+ {
7694
+ style: {
7695
+ display: "flex",
7696
+ alignItems: "center",
7697
+ justifyContent: "center",
7698
+ height: "100%",
7699
+ color: "var(--color-text-3, #9ca3af)",
7700
+ fontSize: "12px"
7701
+ },
7702
+ children: "No document"
7703
+ }
7704
+ )
7705
+ }
7706
+ )
8009
7707
  }
8010
7708
  ) });
8011
7709
  }
8012
- async function loadDatatype(id) {
8013
- try {
8014
- const registry = getRegistry("patchwork:datatype");
8015
- return await registry.load(id);
8016
- } catch {
8017
- return void 0;
8018
- }
8019
- }
8020
7710
 
8021
7711
  // src/NewDocTool.tsx
8022
7712
  var import_react9 = __toESM(require_react(), 1);
8023
7713
  var import_react_dom = __toESM(require_react_dom(), 1);
8024
7714
  import {
8025
7715
  createDocOfDatatype2,
8026
- getRegistry as getRegistry2
7716
+ getRegistry
8027
7717
  } from "@inkandswitch/patchwork-plugins";
8028
7718
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
8029
7719
  var _contextByEditor = /* @__PURE__ */ new WeakMap();
@@ -8036,15 +7726,15 @@ function setSelectedDatatypeId(id) {
8036
7726
  }
8037
7727
  function getListedDatatypeDescriptions() {
8038
7728
  try {
8039
- const registry = getRegistry2("patchwork:datatype");
7729
+ const registry = getRegistry("patchwork:datatype");
8040
7730
  return registry.filter((d) => !d.unlisted);
8041
7731
  } catch {
8042
7732
  return [];
8043
7733
  }
8044
7734
  }
8045
- async function loadDatatype2(id) {
7735
+ async function loadDatatype(id) {
8046
7736
  try {
8047
- const registry = getRegistry2("patchwork:datatype");
7737
+ const registry = getRegistry("patchwork:datatype");
8048
7738
  return await registry.load(id);
8049
7739
  } catch {
8050
7740
  return void 0;
@@ -8141,7 +7831,7 @@ var NewDocShapeTool = class extends StateNode {
8141
7831
  editor.setSelectedShapes([placeholderId]);
8142
7832
  void (async () => {
8143
7833
  try {
8144
- const datatype = await loadDatatype2(datatypeId);
7834
+ const datatype = await loadDatatype(datatypeId);
8145
7835
  if (!datatype) throw new Error(`Could not load datatype: ${datatypeId}`);
8146
7836
  const docHandle = await createDocOfDatatype2(datatype, repo);
8147
7837
  const docUrl = docHandle.url;
@@ -8672,12 +8362,16 @@ function usePatchworkDrop(element) {
8672
8362
  const isInsideEmbeddedPatchworkView = (e) => {
8673
8363
  for (const el of e.composedPath()) {
8674
8364
  if (el === element) break;
8675
- if (el.tagName?.toLowerCase() === "patchwork-view") return true;
8365
+ if (el.tagName?.toLowerCase() === "patchwork-view")
8366
+ return true;
8676
8367
  }
8677
8368
  return false;
8678
8369
  };
8679
8370
  const allowDrop = (e) => {
8680
- if (e.dataTransfer && isPatchworkDrag(e.dataTransfer.types)) e.preventDefault();
8371
+ if (e.dataTransfer && isPatchworkDrag(e.dataTransfer.types)) {
8372
+ e.preventDefault();
8373
+ e.dataTransfer.dropEffect = "link";
8374
+ }
8681
8375
  };
8682
8376
  const handleDrop = (e) => {
8683
8377
  if (!e.dataTransfer || !isPatchworkDrag(e.dataTransfer.types)) return;
@@ -8688,12 +8382,10 @@ function usePatchworkDrop(element) {
8688
8382
  if (docs.length === 0) return;
8689
8383
  const dropPoint = editor.screenToPage({ x: e.clientX, y: e.clientY });
8690
8384
  const STAGGER = 24;
8385
+ const createdIds = [];
8691
8386
  docs.forEach((item, i) => {
8692
- const shapeId = makeShapeId(item.url);
8693
- if (editor.getShape(shapeId)) {
8694
- editor.select(shapeId);
8695
- return;
8696
- }
8387
+ const shapeId = createShapeId();
8388
+ createdIds.push(shapeId);
8697
8389
  const knownType = item.type ?? "";
8698
8390
  editor.createShape({
8699
8391
  id: shapeId,
@@ -8733,7 +8425,7 @@ function usePatchworkDrop(element) {
8733
8425
  })();
8734
8426
  }
8735
8427
  });
8736
- editor.setSelectedShapes(docs.map((d) => makeShapeId(d.url)));
8428
+ editor.setSelectedShapes(createdIds);
8737
8429
  };
8738
8430
  element.addEventListener("dragenter", allowDrop, { capture: true });
8739
8431
  element.addEventListener("dragover", allowDrop, { capture: true });