quoin-editor 1.0.0 → 1.0.2

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.
Files changed (213) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/ai.cjs +135 -94
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.js +62 -21
  7. package/dist/ai.js.map +1 -1
  8. package/dist/catalogue.cjs +25 -25
  9. package/dist/catalogue.d.cts +6 -6
  10. package/dist/catalogue.d.ts +6 -6
  11. package/dist/catalogue.js +17 -17
  12. package/dist/{chunk-ND5XJVK2.cjs → chunk-4SLJNZSM.cjs} +27 -23
  13. package/dist/chunk-4SLJNZSM.cjs.map +1 -0
  14. package/dist/{chunk-LCQSG4M6.js → chunk-4XFXB37X.js} +22 -18
  15. package/dist/chunk-4XFXB37X.js.map +1 -0
  16. package/dist/{chunk-AEJXZBVR.cjs → chunk-5MAYUGTE.cjs} +110 -103
  17. package/dist/chunk-5MAYUGTE.cjs.map +1 -0
  18. package/dist/{chunk-JDPTZUBW.js → chunk-623AOJM2.js} +4 -4
  19. package/dist/chunk-6NULZPVC.js +374 -0
  20. package/dist/chunk-6NULZPVC.js.map +1 -0
  21. package/dist/{chunk-2QCRZ7OL.cjs → chunk-6V6GGBDK.cjs} +12 -11
  22. package/dist/{chunk-2QCRZ7OL.cjs.map → chunk-6V6GGBDK.cjs.map} +1 -1
  23. package/dist/{chunk-WXMYDXPN.cjs → chunk-73653CJ4.cjs} +4 -3
  24. package/dist/chunk-73653CJ4.cjs.map +1 -0
  25. package/dist/{chunk-47MLKSI2.js → chunk-ADSJ42DO.js} +6 -6
  26. package/dist/{chunk-PWUEPDA3.cjs → chunk-AUOEM3SF.cjs} +44 -44
  27. package/dist/{chunk-PWUEPDA3.cjs.map → chunk-AUOEM3SF.cjs.map} +1 -1
  28. package/dist/{chunk-WQHV3MRE.cjs → chunk-BQANU5BH.cjs} +12 -12
  29. package/dist/{chunk-WQHV3MRE.cjs.map → chunk-BQANU5BH.cjs.map} +1 -1
  30. package/dist/{chunk-KXOBZGQO.js → chunk-C23RQVRK.js} +21 -14
  31. package/dist/chunk-C23RQVRK.js.map +1 -0
  32. package/dist/{chunk-2VDK27IF.cjs → chunk-CW3AFJBR.cjs} +312 -342
  33. package/dist/chunk-CW3AFJBR.cjs.map +1 -0
  34. package/dist/{chunk-MQ2XQ4MX.js → chunk-DUE3HCZD.js} +6 -6
  35. package/dist/chunk-DUE3HCZD.js.map +1 -0
  36. package/dist/{chunk-OMOBMXD5.cjs → chunk-EH5KXQXY.cjs} +7 -2
  37. package/dist/chunk-EH5KXQXY.cjs.map +1 -0
  38. package/dist/{chunk-ZS2WA357.js → chunk-EPARJI4V.js} +147 -129
  39. package/dist/chunk-EPARJI4V.js.map +1 -0
  40. package/dist/{chunk-HZSSEYJS.cjs → chunk-FDRUAL3Z.cjs} +30 -30
  41. package/dist/{chunk-HZSSEYJS.cjs.map → chunk-FDRUAL3Z.cjs.map} +1 -1
  42. package/dist/{chunk-T7SW6OWV.js → chunk-IQBMAE3F.js} +5 -5
  43. package/dist/{chunk-RUDWMKYX.js → chunk-JHQUHFLX.js} +8 -8
  44. package/dist/{chunk-HELJTLNC.cjs → chunk-KUYZMSMF.cjs} +12 -12
  45. package/dist/chunk-KUYZMSMF.cjs.map +1 -0
  46. package/dist/chunk-LE5XMIFJ.cjs +14 -0
  47. package/dist/chunk-LE5XMIFJ.cjs.map +1 -0
  48. package/dist/{chunk-EL2OEJQC.cjs → chunk-LLTEGXWZ.cjs} +56 -56
  49. package/dist/{chunk-EL2OEJQC.cjs.map → chunk-LLTEGXWZ.cjs.map} +1 -1
  50. package/dist/chunk-MQUCCSWG.js +14 -0
  51. package/dist/chunk-MQUCCSWG.js.map +1 -0
  52. package/dist/{chunk-NNDYYEW5.js → chunk-N4FGA3H4.js} +5 -5
  53. package/dist/{chunk-ZHOSSWUM.js → chunk-NEZJ7ZP5.js} +4 -3
  54. package/dist/chunk-NEZJ7ZP5.js.map +1 -0
  55. package/dist/{chunk-XEBWC7ZL.js → chunk-O4Z2WMFF.js} +7 -2
  56. package/dist/chunk-O4Z2WMFF.js.map +1 -0
  57. package/dist/{chunk-HJIQT3S5.js → chunk-OBMBSU2S.js} +100 -84
  58. package/dist/chunk-OBMBSU2S.js.map +1 -0
  59. package/dist/{chunk-KAVU6T6J.js → chunk-OSHZQR3W.js} +5 -5
  60. package/dist/{chunk-GTTPVJSD.cjs → chunk-P6KYXFZC.cjs} +265 -247
  61. package/dist/chunk-P6KYXFZC.cjs.map +1 -0
  62. package/dist/{chunk-CDELOHDY.cjs → chunk-R2BLBV43.cjs} +23 -23
  63. package/dist/{chunk-CDELOHDY.cjs.map → chunk-R2BLBV43.cjs.map} +1 -1
  64. package/dist/{chunk-NOKWNK2O.js → chunk-RJRX34BZ.js} +3 -2
  65. package/dist/{chunk-ZGZEJCRV.js → chunk-T43RZTUT.js} +166 -196
  66. package/dist/chunk-T43RZTUT.js.map +1 -0
  67. package/dist/chunk-TLGX43P6.cjs +374 -0
  68. package/dist/chunk-TLGX43P6.cjs.map +1 -0
  69. package/dist/{chunk-POBM7MGR.js → chunk-U3LOLYAU.js} +2 -2
  70. package/dist/{chunk-RDG4VI6E.cjs → chunk-UEKXVCKC.cjs} +103 -93
  71. package/dist/chunk-UEKXVCKC.cjs.map +1 -0
  72. package/dist/{chunk-PMWCQSQX.js → chunk-VCLL5C7J.js} +5 -5
  73. package/dist/{chunk-SG37UBDO.js → chunk-VRS6WCEK.js} +20 -10
  74. package/dist/chunk-VRS6WCEK.js.map +1 -0
  75. package/dist/{chunk-ZC24WB7Y.cjs → chunk-WEYDDIBQ.cjs} +14 -14
  76. package/dist/{chunk-ZC24WB7Y.cjs.map → chunk-WEYDDIBQ.cjs.map} +1 -1
  77. package/dist/{chunk-5DNCCN6X.cjs → chunk-X4HDKFW5.cjs} +27 -27
  78. package/dist/{chunk-5DNCCN6X.cjs.map → chunk-X4HDKFW5.cjs.map} +1 -1
  79. package/dist/{chunk-SLVDAHHK.cjs → chunk-X4P4TQXH.cjs} +5 -5
  80. package/dist/{chunk-SLVDAHHK.cjs.map → chunk-X4P4TQXH.cjs.map} +1 -1
  81. package/dist/{chunk-GLLXHMH2.cjs → chunk-XA3UEJIW.cjs} +3 -3
  82. package/dist/{chunk-GLLXHMH2.cjs.map → chunk-XA3UEJIW.cjs.map} +1 -1
  83. package/dist/{chunk-K574XHMM.js → chunk-YBMUEEM5.js} +2 -2
  84. package/dist/{chunk-PZ4GT5JO.cjs → chunk-ZKVOS57Q.cjs} +316 -300
  85. package/dist/chunk-ZKVOS57Q.cjs.map +1 -0
  86. package/dist/comments.cjs +113 -98
  87. package/dist/comments.cjs.map +1 -1
  88. package/dist/comments.d.cts +6 -1
  89. package/dist/comments.d.ts +6 -1
  90. package/dist/comments.js +32 -17
  91. package/dist/comments.js.map +1 -1
  92. package/dist/diff.cjs +44 -40
  93. package/dist/diff.cjs.map +1 -1
  94. package/dist/diff.js +17 -13
  95. package/dist/diff.js.map +1 -1
  96. package/dist/docx.cjs +60 -40
  97. package/dist/docx.cjs.map +1 -1
  98. package/dist/docx.d.cts +6 -0
  99. package/dist/docx.d.ts +6 -0
  100. package/dist/docx.js +32 -12
  101. package/dist/docx.js.map +1 -1
  102. package/dist/embed.cjs +9 -9
  103. package/dist/embed.d.cts +1 -1
  104. package/dist/embed.d.ts +1 -1
  105. package/dist/embed.js +8 -8
  106. package/dist/{emoji-extension-DpQ43HjE.d.ts → emoji-extension-CmPlRssm.d.ts} +1 -1
  107. package/dist/{emoji-extension-C12gDPm6.d.cts → emoji-extension-zJ6F7hW8.d.cts} +1 -1
  108. package/dist/emoji.cjs +8 -8
  109. package/dist/emoji.d.cts +3 -3
  110. package/dist/emoji.d.ts +3 -3
  111. package/dist/emoji.js +7 -7
  112. package/dist/engine.cjs +4 -4
  113. package/dist/engine.d.cts +2 -2
  114. package/dist/engine.d.ts +2 -2
  115. package/dist/engine.js +3 -3
  116. package/dist/{find-extension-_sbZEt3R.d.cts → find-extension-BcRyE9K4.d.cts} +1 -1
  117. package/dist/{find-extension-DKqLLSuP.d.ts → find-extension-CmFehyul.d.ts} +1 -1
  118. package/dist/find.cjs +8 -8
  119. package/dist/find.d.cts +2 -2
  120. package/dist/find.d.ts +2 -2
  121. package/dist/find.js +7 -7
  122. package/dist/headless.cjs +5 -5
  123. package/dist/headless.d.cts +4 -4
  124. package/dist/headless.d.ts +4 -4
  125. package/dist/headless.js +4 -4
  126. package/dist/{index-CgD72kHB.d.cts → index-CFPmCee4.d.cts} +5 -2
  127. package/dist/{index-DNYbTK3w.d.ts → index-DiCGV60d.d.ts} +5 -2
  128. package/dist/index.cjs +7 -7
  129. package/dist/index.d.cts +4 -4
  130. package/dist/index.d.ts +4 -4
  131. package/dist/index.js +6 -6
  132. package/dist/math.cjs +10 -10
  133. package/dist/math.d.cts +1 -1
  134. package/dist/math.d.ts +1 -1
  135. package/dist/math.js +9 -9
  136. package/dist/mention.cjs +10 -10
  137. package/dist/mention.d.cts +1 -1
  138. package/dist/mention.d.ts +1 -1
  139. package/dist/mention.js +9 -9
  140. package/dist/presence.cjs +98 -104
  141. package/dist/presence.cjs.map +1 -1
  142. package/dist/presence.d.cts +2 -2
  143. package/dist/presence.d.ts +2 -2
  144. package/dist/presence.js +66 -72
  145. package/dist/presence.js.map +1 -1
  146. package/dist/{stats-extension-Bly88uio.d.ts → stats-extension-DisOEbbI.d.ts} +1 -1
  147. package/dist/{stats-extension-CJPijvUb.d.cts → stats-extension-Dt1lgP3m.d.cts} +1 -1
  148. package/dist/stats.cjs +9 -9
  149. package/dist/stats.d.cts +3 -3
  150. package/dist/stats.d.ts +3 -3
  151. package/dist/stats.js +8 -8
  152. package/dist/styles.css +1 -1
  153. package/dist/{table-extension-Dzf4k6hI.d.ts → table-extension-BTMJnT7J.d.ts} +1 -1
  154. package/dist/{table-extension-BTLxFy2S.d.cts → table-extension-DxZz3jqp.d.cts} +1 -1
  155. package/dist/table.cjs +8 -8
  156. package/dist/table.d.cts +2 -2
  157. package/dist/table.d.ts +2 -2
  158. package/dist/table.js +7 -7
  159. package/dist/{toc-extension-DWm5alVj.d.ts → toc-extension-CR9U-l6j.d.ts} +1 -1
  160. package/dist/{toc-extension-B3-s6h2x.d.cts → toc-extension-DGHywOBv.d.cts} +1 -1
  161. package/dist/toc.cjs +8 -8
  162. package/dist/toc.d.cts +2 -2
  163. package/dist/toc.d.ts +2 -2
  164. package/dist/toc.js +7 -7
  165. package/dist/{types-a1CRBlEh.d.ts → types-C6_QkXzy.d.ts} +1 -9
  166. package/dist/{types-Cz7XJLaK.d.cts → types-CJ7Gq3GX.d.cts} +1 -9
  167. package/dist/{view-controller-DSHw0ltQ.d.cts → view-controller-BD1KwYfE.d.cts} +6 -19
  168. package/dist/{view-controller-UbpzblGl.d.ts → view-controller-y4cb60ue.d.ts} +6 -19
  169. package/dist/view.cjs +6 -6
  170. package/dist/view.js +3 -3
  171. package/dist/yjs.cjs +302 -412
  172. package/dist/yjs.cjs.map +1 -1
  173. package/dist/yjs.d.cts +3 -3
  174. package/dist/yjs.d.ts +3 -3
  175. package/dist/yjs.js +211 -321
  176. package/dist/yjs.js.map +1 -1
  177. package/package.json +1 -1
  178. package/dist/chunk-2VDK27IF.cjs.map +0 -1
  179. package/dist/chunk-AEJXZBVR.cjs.map +0 -1
  180. package/dist/chunk-E75EHRPA.cjs +0 -175
  181. package/dist/chunk-E75EHRPA.cjs.map +0 -1
  182. package/dist/chunk-GTTPVJSD.cjs.map +0 -1
  183. package/dist/chunk-HELJTLNC.cjs.map +0 -1
  184. package/dist/chunk-HJIQT3S5.js.map +0 -1
  185. package/dist/chunk-JEIFJHEI.js +0 -14
  186. package/dist/chunk-JEIFJHEI.js.map +0 -1
  187. package/dist/chunk-KXOBZGQO.js.map +0 -1
  188. package/dist/chunk-LCQSG4M6.js.map +0 -1
  189. package/dist/chunk-MQ2XQ4MX.js.map +0 -1
  190. package/dist/chunk-ND5XJVK2.cjs.map +0 -1
  191. package/dist/chunk-OMOBMXD5.cjs.map +0 -1
  192. package/dist/chunk-PZ4GT5JO.cjs.map +0 -1
  193. package/dist/chunk-QAW5NH6S.cjs +0 -14
  194. package/dist/chunk-QAW5NH6S.cjs.map +0 -1
  195. package/dist/chunk-RDG4VI6E.cjs.map +0 -1
  196. package/dist/chunk-SG37UBDO.js.map +0 -1
  197. package/dist/chunk-TC4DARU2.js +0 -175
  198. package/dist/chunk-TC4DARU2.js.map +0 -1
  199. package/dist/chunk-WXMYDXPN.cjs.map +0 -1
  200. package/dist/chunk-XEBWC7ZL.js.map +0 -1
  201. package/dist/chunk-ZGZEJCRV.js.map +0 -1
  202. package/dist/chunk-ZHOSSWUM.js.map +0 -1
  203. package/dist/chunk-ZS2WA357.js.map +0 -1
  204. /package/dist/{chunk-JDPTZUBW.js.map → chunk-623AOJM2.js.map} +0 -0
  205. /package/dist/{chunk-47MLKSI2.js.map → chunk-ADSJ42DO.js.map} +0 -0
  206. /package/dist/{chunk-T7SW6OWV.js.map → chunk-IQBMAE3F.js.map} +0 -0
  207. /package/dist/{chunk-RUDWMKYX.js.map → chunk-JHQUHFLX.js.map} +0 -0
  208. /package/dist/{chunk-NNDYYEW5.js.map → chunk-N4FGA3H4.js.map} +0 -0
  209. /package/dist/{chunk-KAVU6T6J.js.map → chunk-OSHZQR3W.js.map} +0 -0
  210. /package/dist/{chunk-NOKWNK2O.js.map → chunk-RJRX34BZ.js.map} +0 -0
  211. /package/dist/{chunk-POBM7MGR.js.map → chunk-U3LOLYAU.js.map} +0 -0
  212. /package/dist/{chunk-PMWCQSQX.js.map → chunk-VCLL5C7J.js.map} +0 -0
  213. /package/dist/{chunk-K574XHMM.js.map → chunk-YBMUEEM5.js.map} +0 -0
@@ -41,11 +41,12 @@ import {
41
41
  toggleTask,
42
42
  undo,
43
43
  undoInputRule
44
- } from "./chunk-HJIQT3S5.js";
44
+ } from "./chunk-OBMBSU2S.js";
45
45
  import {
46
46
  alignOrUndefined,
47
47
  blockById,
48
48
  dataAttributes,
49
+ firstNamed,
49
50
  headingLevel,
50
51
  inlineLength,
51
52
  inlinePlainText,
@@ -61,7 +62,7 @@ import {
61
62
  sanitizeHref,
62
63
  sliceInline,
63
64
  writtenAttrs
64
- } from "./chunk-LCQSG4M6.js";
65
+ } from "./chunk-4XFXB37X.js";
65
66
 
66
67
  // src/view/react/use-editor-state.ts
67
68
  import { useCallback, useRef, useSyncExternalStore } from "react";
@@ -610,6 +611,15 @@ function writeSelection(registry, selection, domSelection, blockElement) {
610
611
  return true;
611
612
  }
612
613
 
614
+ // src/view/dom/listen.ts
615
+ function listen(target, handlers, options) {
616
+ const entries = Object.entries(handlers);
617
+ for (const [type, handler] of entries) target.addEventListener(type, handler, options);
618
+ return () => {
619
+ for (const [type, handler] of entries) target.removeEventListener(type, handler, options);
620
+ };
621
+ }
622
+
613
623
  // src/view/navigation/node-entry.ts
614
624
  var NODE_ENTRY = "data-quoin-node-entry";
615
625
  var entersAsNode = (controller, block) => controller.blockElement(block)?.querySelector(`[${NODE_ENTRY}]`) != null;
@@ -829,6 +839,8 @@ function createCrossBlockPointer(controller) {
829
839
  const doc = root.ownerDocument;
830
840
  const view = doc.defaultView;
831
841
  let press = null;
842
+ let unfollow = () => {
843
+ };
832
844
  let last = { x: 0, y: 0 };
833
845
  let preventMouseDown = false;
834
846
  const scroll = createAutoScroll(root, () => follow(last.x, last.y));
@@ -863,10 +875,7 @@ function createCrossBlockPointer(controller) {
863
875
  else if (press?.kind === "blocks") followBlocks(press, x, y);
864
876
  }
865
877
  function release() {
866
- doc.removeEventListener("pointermove", onPointerMove);
867
- doc.removeEventListener("pointerup", end);
868
- doc.removeEventListener("pointercancel", end);
869
- view.removeEventListener("blur", end);
878
+ unfollow();
870
879
  scroll.stop();
871
880
  press = null;
872
881
  const dragged = controller.dragging;
@@ -912,21 +921,21 @@ function createCrossBlockPointer(controller) {
912
921
  } else {
913
922
  return;
914
923
  }
915
- doc.addEventListener("pointermove", onPointerMove);
916
- doc.addEventListener("pointerup", end);
917
- doc.addEventListener("pointercancel", end);
918
- view.addEventListener("blur", end);
924
+ const unfollowDocument = listen(doc, { pointermove: onPointerMove, pointerup: end, pointercancel: end });
925
+ const unfollowView = listen(view, { blur: end });
926
+ unfollow = () => {
927
+ unfollowDocument();
928
+ unfollowView();
929
+ };
919
930
  }
920
931
  function onMouseDown(event) {
921
932
  if (preventMouseDown) event.preventDefault();
922
933
  preventMouseDown = false;
923
934
  }
924
- root.addEventListener("pointerdown", onPointerDown);
925
- root.addEventListener("mousedown", onMouseDown);
935
+ const unlisten = listen(root, { pointerdown: onPointerDown, mousedown: onMouseDown });
926
936
  return () => {
927
937
  release();
928
- root.removeEventListener("pointerdown", onPointerDown);
929
- root.removeEventListener("mousedown", onMouseDown);
938
+ unlisten();
930
939
  };
931
940
  }
932
941
  };
@@ -1098,19 +1107,27 @@ var nodeOf = (selection) => selection?.kind === "node" ? selection.block : null;
1098
1107
  function createNodeReveal(element) {
1099
1108
  let shown = null;
1100
1109
  let pressed = null;
1110
+ let owed = null;
1101
1111
  return {
1102
1112
  pressed(block) {
1103
1113
  pressed = block;
1104
1114
  },
1105
1115
  follow(selection) {
1106
- if (nodeOf(selection) !== shown) shown = null;
1116
+ const block = nodeOf(selection);
1117
+ if (block !== shown) shown = null;
1118
+ if (block !== owed) owed = null;
1107
1119
  },
1108
1120
  settle(selection) {
1109
- shown = nodeOf(selection);
1121
+ const block = nodeOf(selection);
1122
+ if (block !== shown) owed = block;
1123
+ shown = block;
1110
1124
  },
1111
- show(selection) {
1125
+ show(selection, local) {
1112
1126
  const block = nodeOf(selection);
1113
- if (block !== null && block !== shown && block !== pressed) element(block)?.scrollIntoView({ block: "nearest" });
1127
+ if (block !== null && block !== pressed && (block !== shown || local && block === owed)) {
1128
+ element(block)?.scrollIntoView({ block: "nearest" });
1129
+ }
1130
+ if (local) owed = null;
1114
1131
  shown = block;
1115
1132
  pressed = null;
1116
1133
  }
@@ -1458,7 +1475,7 @@ function handleDrop(controller, event) {
1458
1475
  return;
1459
1476
  }
1460
1477
  const pos = dropPos(controller, event.clientX, event.clientY);
1461
- if (pos) dispatchSelection(controller, textSelection(pos));
1478
+ if (pos) controller.dispatch(controller.editor.createTransaction().setSelection(textSelection(pos)).setOrigin("drop"));
1462
1479
  pasteTransfer(controller, dataTransfer);
1463
1480
  }
1464
1481
  function handleDragOver(event) {
@@ -1811,7 +1828,7 @@ function targetAt(controller, node) {
1811
1828
  }
1812
1829
  function elementOf(controller, target) {
1813
1830
  if (target === EMPTY_HOST) return controller.emptyHost ?? void 0;
1814
- return target === null ? void 0 : controller.registry.get(target.block, target.region);
1831
+ return target ? controller.registry.get(target.block, target.region) : void 0;
1815
1832
  }
1816
1833
  function createCompositionHandlers(controller) {
1817
1834
  let active = false;
@@ -2286,11 +2303,13 @@ function attachInput(controller, root) {
2286
2303
  else composition.end(event);
2287
2304
  };
2288
2305
  const detachClipboard = attachClipboard(controller, root, catchUp);
2289
- root.addEventListener("keydown", onKeyDown);
2290
- root.addEventListener("beforeinput", onBeforeInput);
2291
- root.addEventListener("input", onInput);
2292
- root.addEventListener("compositionstart", onCompositionStart);
2293
- root.addEventListener("compositionend", onCompositionEnd);
2306
+ const unlisten = listen(root, {
2307
+ keydown: onKeyDown,
2308
+ beforeinput: onBeforeInput,
2309
+ input: onInput,
2310
+ compositionstart: onCompositionStart,
2311
+ compositionend: onCompositionEnd
2312
+ });
2294
2313
  function observe(host) {
2295
2314
  if (!observed.has(host)) observed.set(host, fallback.observe(host));
2296
2315
  }
@@ -2306,11 +2325,7 @@ function attachInput(controller, root) {
2306
2325
  composition.release();
2307
2326
  sinkComposition.release();
2308
2327
  detachClipboard();
2309
- root.removeEventListener("keydown", onKeyDown);
2310
- root.removeEventListener("beforeinput", onBeforeInput);
2311
- root.removeEventListener("input", onInput);
2312
- root.removeEventListener("compositionstart", onCompositionStart);
2313
- root.removeEventListener("compositionend", onCompositionEnd);
2328
+ unlisten();
2314
2329
  for (const stop of observed.values()) stop();
2315
2330
  observed.clear();
2316
2331
  }
@@ -2332,13 +2347,11 @@ function watchFocusReturn(root, handlers) {
2332
2347
  const onFocusOut = (event) => {
2333
2348
  if (!root.contains(event.relatedTarget)) pressed = false;
2334
2349
  };
2335
- root.addEventListener("pointerdown", onPointerDown, true);
2336
- root.addEventListener("focusin", onFocusIn);
2337
- root.addEventListener("focusout", onFocusOut);
2350
+ const unlistenPress = listen(root, { pointerdown: onPointerDown }, true);
2351
+ const unlistenFocus = listen(root, { focusin: onFocusIn, focusout: onFocusOut });
2338
2352
  return () => {
2339
- root.removeEventListener("pointerdown", onPointerDown, true);
2340
- root.removeEventListener("focusin", onFocusIn);
2341
- root.removeEventListener("focusout", onFocusOut);
2353
+ unlistenPress();
2354
+ unlistenFocus();
2342
2355
  };
2343
2356
  }
2344
2357
 
@@ -2409,7 +2422,7 @@ function movedSelection(controller, doc, model) {
2409
2422
  const selection = readSelection(controller.registry, doc.getSelection(), (node) => controller.blockAt(node));
2410
2423
  return selection === null || sameSelection(selection, model) ? null : selection;
2411
2424
  }
2412
- function writeModelSelection(controller, doc, moved) {
2425
+ function writeModelSelection(controller, doc, moved, local) {
2413
2426
  const domSelection = doc?.getSelection();
2414
2427
  if (focusingSink(controller) || controller.composingKey !== null || !doc || !domSelection || !ownsFocus(controller, doc)) {
2415
2428
  return;
@@ -2419,7 +2432,7 @@ function writeModelSelection(controller, doc, moved) {
2419
2432
  if (heldBySink(selection) && controller.sink !== null) focusSink(controller);
2420
2433
  else if (selection?.kind === "blocks") domSelection.removeAllRanges();
2421
2434
  else writeSelection(controller.registry, selection, domSelection, (id) => controller.blockElement(id));
2422
- controller.nodeReveal.show(selection);
2435
+ controller.nodeReveal.show(selection, local);
2423
2436
  if (!samePoints(before, selectionPoints(domSelection))) moved();
2424
2437
  }
2425
2438
 
@@ -2428,102 +2441,105 @@ var runNow = (fn) => fn();
2428
2441
  var ViewController = class {
2429
2442
  editor;
2430
2443
  registry = createHostRegistry((element) => {
2431
- this.binding?.input.observe(element);
2432
- this.drawn.syncTabStop();
2444
+ this.#binding?.input.observe(element);
2445
+ this.#drawn.syncTabStop();
2433
2446
  return () => {
2434
- this.binding?.input.unobserve(element);
2435
- this.drawn.syncTabStop();
2447
+ this.#binding?.input.unobserve(element);
2448
+ this.#drawn.syncTabStop();
2436
2449
  };
2437
2450
  });
2438
2451
  keyInterceptors = /* @__PURE__ */ new Set();
2439
2452
  nodeReveal = createNodeReveal((id) => this.blockElement(id));
2440
- announcer = createAnnouncer(() => this.said);
2453
+ announcer = createAnnouncer(() => this.#said);
2441
2454
  isMac;
2442
2455
  onFiles;
2443
2456
  goalX = null;
2444
2457
  nativeVerticalMove = false;
2445
2458
  dragging = false;
2446
2459
  composingKey = null;
2447
- flush;
2448
- hosts;
2449
- drawn = createDrawnElements(this.registry, () => this.editor.state);
2450
- cross = createCrossMode(this);
2451
- outside = createOutsideChanges(
2452
- () => hasFocus(this, this.ownerDocument()),
2453
- (model) => movedSelection(this, this.ownerDocument(), model)
2460
+ #flush;
2461
+ #hosts;
2462
+ #drawn = createDrawnElements(this.registry, () => this.editor.state);
2463
+ #cross = createCrossMode(this);
2464
+ #outside = createOutsideChanges(
2465
+ () => hasFocus(this, this.#ownerDocument()),
2466
+ (model) => movedSelection(this, this.#ownerDocument(), model)
2454
2467
  );
2455
- binding = null;
2456
- quiet = false;
2457
- said;
2458
- detachRoot = null;
2459
- readOnlyState;
2468
+ #binding = null;
2469
+ #quiet = false;
2470
+ #loud = false;
2471
+ #said;
2472
+ #detachRoot = null;
2473
+ #readOnlyState;
2460
2474
  constructor(options) {
2461
2475
  this.editor = options.editor;
2462
2476
  options.editor.subscribe((state, tr) => {
2463
- if (tr?.origin !== "remote") this.said = state;
2477
+ if (tr?.origin !== "remote") this.#said = state;
2464
2478
  });
2465
- this.flush = options.flush ?? runNow;
2479
+ this.#flush = options.flush ?? runNow;
2466
2480
  this.onFiles = options.onFiles;
2467
2481
  this.isMac = options.isMac ?? detectMac();
2468
2482
  const decorationsOf = (block, region) => this.decorationsFor(block, region);
2469
- this.hosts = createHostRenderer(options.editor, options.render, decorationsOf, (host) => this.binding?.input.drain(host));
2470
- this.readOnlyState = createReadOnly(this.registry, options.readOnly ?? false);
2483
+ const drain = (element) => this.#binding?.input.drain(element);
2484
+ this.#hosts = createHostRenderer(options.editor, options.render, decorationsOf, drain);
2485
+ this.#readOnlyState = createReadOnly(this.registry, options.readOnly ?? false);
2471
2486
  }
2472
2487
  get root() {
2473
- return this.binding?.root ?? null;
2488
+ return this.#binding?.root ?? null;
2474
2489
  }
2475
2490
  get readOnly() {
2476
- return this.readOnlyState.current();
2491
+ return this.#readOnlyState.current();
2477
2492
  }
2478
2493
  get sink() {
2479
- return this.drawn.sink;
2494
+ return this.#drawn.sink;
2480
2495
  }
2481
2496
  get emptyHost() {
2482
- return this.drawn.emptyHost;
2497
+ return this.#drawn.emptyHost;
2483
2498
  }
2484
2499
  attach(root) {
2485
- this.detachRoot?.();
2486
- const binding = bindRoot(this, root, this.cross, (_, tr) => {
2487
- this.quiet ||= tr?.origin === "remote";
2488
- this.outside.committed(tr);
2500
+ this.#detachRoot?.();
2501
+ const binding = bindRoot(this, root, this.#cross, (_, tr) => {
2502
+ this.#quiet ||= tr?.origin === "remote" && tr.docChanged;
2503
+ this.#loud ||= tr?.origin !== "remote";
2504
+ this.#outside.committed(tr);
2489
2505
  this.nodeReveal.follow(this.editor.state.selection);
2490
- this.drawn.syncTabStop();
2491
- this.cross.syncLater();
2506
+ this.#drawn.syncTabStop();
2507
+ this.#cross.syncLater();
2492
2508
  });
2493
2509
  const unmount = this.editor.mount();
2494
2510
  const detach = () => {
2495
2511
  unmount();
2496
2512
  binding.detach();
2497
- if (this.detachRoot !== detach) return;
2498
- this.detachRoot = null;
2499
- this.binding = null;
2513
+ if (this.#detachRoot !== detach) return;
2514
+ this.#detachRoot = null;
2515
+ this.#binding = null;
2500
2516
  };
2501
- this.binding = binding;
2502
- this.detachRoot = detach;
2503
- this.drawn.syncTabStop();
2517
+ this.#binding = binding;
2518
+ this.#detachRoot = detach;
2519
+ this.#drawn.syncTabStop();
2504
2520
  return detach;
2505
2521
  }
2506
2522
  registerBlockElement(id, element) {
2507
- return this.drawn.registerBlock(id, element);
2523
+ return this.#drawn.registerBlock(id, element);
2508
2524
  }
2509
2525
  blockElement(id) {
2510
- return this.drawn.block(id);
2526
+ return this.#drawn.block(id);
2511
2527
  }
2512
2528
  blockAt(node) {
2513
- return this.drawn.blockAt(node);
2529
+ return this.#drawn.blockAt(node);
2514
2530
  }
2515
2531
  registerSink(element) {
2516
- return this.drawn.registerSink(element);
2532
+ return this.#drawn.registerSink(element);
2517
2533
  }
2518
2534
  // An empty document draws one host that stands for a paragraph not created yet, so it belongs to no block.
2519
2535
  registerEmptyHost(element) {
2520
- return this.drawn.registerEmptyHost(element);
2536
+ return this.#drawn.registerEmptyHost(element);
2521
2537
  }
2522
2538
  isEditorElement(element) {
2523
- return this.drawn.isEditorElement(element);
2539
+ return this.#drawn.isEditorElement(element);
2524
2540
  }
2525
2541
  decorationsFor(block, region) {
2526
- return hostDecorations(this.editor, block, region, this.cross.mode);
2542
+ return hostDecorations(this.editor, block, region, this.#cross.mode);
2527
2543
  }
2528
2544
  dispatch(tr) {
2529
2545
  this.edit(() => {
@@ -2536,34 +2552,35 @@ var ViewController = class {
2536
2552
  // open a popover that takes it.
2537
2553
  edit(change) {
2538
2554
  const before = this.editor.state;
2539
- const doc = this.ownerDocument();
2555
+ const doc = this.#ownerDocument();
2540
2556
  const focused = hasFocus(this, doc);
2541
2557
  let handled = false;
2542
- this.flush(
2543
- () => this.outside.inside(() => {
2558
+ this.#flush(
2559
+ () => this.#outside.inside(() => {
2544
2560
  handled = change();
2545
2561
  })
2546
2562
  );
2547
2563
  if (this.editor.state === before) return handled;
2548
2564
  if (this.editor.state.doc !== before.doc) this.goalX = null;
2549
2565
  this.refreshHosts();
2550
- this.cross.sync();
2551
- if (focused && doc !== null && ownsFocus(this, doc)) this.keepFocus();
2552
- this.syncSelectionToDom();
2566
+ this.#cross.sync();
2567
+ if (focused && doc !== null && ownsFocus(this, doc)) this.#keepFocus();
2568
+ this.syncSelectionToDom(true);
2553
2569
  return handled;
2554
2570
  }
2555
2571
  // A change made outside edit() reaches the hosts when React draws them, so the selection is written back once that
2556
- // has happened, and focus follows a host the change replaced. A collaborator's change scrolls nothing doing so.
2572
+ // has happened, and focus follows a host the change replaced. A render of collaborators' changes alone, or of one
2573
+ // that changed the document, scrolls nothing doing so; a caret move of theirs leaves the rest to scroll as it would.
2557
2574
  afterRender() {
2558
- const { quiet } = this;
2559
- this.quiet = false;
2560
- const doc = this.ownerDocument();
2561
- const moved = this.outside.takeMoved();
2562
- if (!this.outside.takeFocused() || !doc || !ownsFocus(this, doc)) return;
2563
- if (moved) this.selectFromDom(moved);
2564
- this.cross.sync();
2575
+ const quiet = this.#quiet || !this.#loud;
2576
+ this.#quiet = this.#loud = false;
2577
+ const doc = this.#ownerDocument();
2578
+ const moved = this.#outside.takeMoved();
2579
+ if (!this.#outside.takeFocused() || !doc || !ownsFocus(this, doc)) return;
2580
+ if (moved) this.#selectFromDom(moved);
2581
+ this.#cross.sync();
2565
2582
  const follow = () => {
2566
- this.keepFocus(quiet);
2583
+ this.#keepFocus(quiet);
2567
2584
  this.syncSelectionToDom();
2568
2585
  };
2569
2586
  if (!quiet) return follow();
@@ -2572,7 +2589,7 @@ var ViewController = class {
2572
2589
  }
2573
2590
  refreshHosts() {
2574
2591
  for (const host of this.registry.all()) {
2575
- if (!this.isComposing(host)) this.hosts.renderIfChanged(host);
2592
+ if (!this.#isComposing(host)) this.#hosts.renderIfChanged(host);
2576
2593
  }
2577
2594
  }
2578
2595
  run(command) {
@@ -2587,63 +2604,63 @@ var ViewController = class {
2587
2604
  renderHost(block, region) {
2588
2605
  const element = this.registry.get(block, region);
2589
2606
  const host = element && { block, region, element };
2590
- if (!host || this.isComposing(host) || !this.hosts.render(host)) return;
2607
+ if (!host || this.#isComposing(host) || !this.#hosts.render(host)) return;
2591
2608
  const inSelection = element.contains(this.domSelection()?.focusNode ?? null);
2592
2609
  if (inSelection && hasFocus(this, element.ownerDocument)) this.syncSelectionToDom();
2593
2610
  }
2594
2611
  domSelection() {
2595
- return this.ownerDocument()?.getSelection() ?? null;
2612
+ return this.#ownerDocument()?.getSelection() ?? null;
2596
2613
  }
2597
- syncSelectionToDom() {
2598
- writeModelSelection(this, this.ownerDocument(), () => this.binding?.selectionSync.suppressNext());
2614
+ syncSelectionToDom(local) {
2615
+ writeModelSelection(this, this.#ownerDocument(), () => this.#binding?.selectionSync.suppressNext(), local);
2599
2616
  }
2600
2617
  // A pointer drag across hosts sets the model selection itself, while the browser keeps extending its own. Leaving
2601
2618
  // cross mode re-renders the hosts that drew it as decorations, which can remove the node holding the caret, so the
2602
2619
  // selection is written back.
2603
2620
  readSelectionFromDom() {
2604
- const selection = movedSelection(this, this.ownerDocument(), this.editor.state.selection);
2621
+ const selection = movedSelection(this, this.#ownerDocument(), this.editor.state.selection);
2605
2622
  if (selection === null) return;
2606
- const wasCross = this.cross.active;
2623
+ const wasCross = this.#cross.active;
2607
2624
  if (!this.nativeVerticalMove) this.goalX = null;
2608
- this.flush(() => this.selectFromDom(selection));
2609
- this.cross.sync();
2610
- if (!wasCross && !this.cross.active) return;
2611
- this.keepFocus();
2625
+ this.#flush(() => this.#selectFromDom(selection));
2626
+ this.#cross.sync();
2627
+ if (!wasCross && !this.#cross.active) return;
2628
+ this.#keepFocus();
2612
2629
  this.syncSelectionToDom();
2613
2630
  }
2614
2631
  focus(target) {
2615
2632
  const { editor } = this;
2616
2633
  const selection = focusTarget(editor.state, target);
2617
2634
  if (selection !== null && !sameSelection(selection, editor.state.selection)) dispatchSelection(this, selection);
2618
- this.takeFocus();
2635
+ this.#takeFocus();
2619
2636
  this.syncSelectionToDom();
2620
2637
  }
2621
2638
  setReadOnly(readOnly) {
2622
- this.readOnlyState.set(readOnly);
2639
+ this.#readOnlyState.set(readOnly);
2623
2640
  }
2624
2641
  subscribeReadOnly(listener) {
2625
- return this.readOnlyState.subscribe(listener);
2642
+ return this.#readOnlyState.subscribe(listener);
2626
2643
  }
2627
2644
  destroy() {
2628
- this.detachRoot?.();
2645
+ this.#detachRoot?.();
2629
2646
  }
2630
- selectFromDom(selection) {
2647
+ #selectFromDom(selection) {
2631
2648
  const { editor } = this;
2632
- this.outside.inside(() => editor.dispatch(editor.createTransaction().setSelection(selection).setOrigin("input")));
2649
+ this.#outside.inside(() => editor.dispatch(editor.createTransaction().setSelection(selection).setOrigin("input")));
2633
2650
  }
2634
- isComposing(host) {
2651
+ #isComposing(host) {
2635
2652
  return this.composingKey !== null && hostKey(host.block, host.region) === this.composingKey;
2636
2653
  }
2637
- ownerDocument() {
2638
- return (this.binding?.root ?? this.registry.all().next().value?.element)?.ownerDocument ?? null;
2654
+ #ownerDocument() {
2655
+ return (this.#binding?.root ?? this.registry.all().next().value?.element)?.ownerDocument ?? null;
2639
2656
  }
2640
2657
  // React replaces a host whose block changes kind, which drops focus, and Firefox does not move focus into another
2641
2658
  // host when a script selects inside it.
2642
- keepFocus(preventScroll) {
2643
- if (this.composingKey === null) this.takeFocus(preventScroll);
2659
+ #keepFocus(preventScroll) {
2660
+ if (this.composingKey === null) this.#takeFocus(preventScroll);
2644
2661
  }
2645
- takeFocus(preventScroll) {
2646
- const element = this.drawn.focusElement();
2662
+ #takeFocus(preventScroll) {
2663
+ const element = this.#drawn.focusElement();
2647
2664
  if (!element || element.ownerDocument.activeElement === element) return;
2648
2665
  if (element === this.sink) focusSink(this);
2649
2666
  else element.focus({ preventScroll });
@@ -2722,7 +2739,7 @@ function SelectionSink({ label = "Selected content", blockLabel }) {
2722
2739
  );
2723
2740
  useIsomorphicLayoutEffect(() => {
2724
2741
  const sink = ref.current;
2725
- return sink === null ? void 0 : controller.registerSink(sink);
2742
+ return sink ? controller.registerSink(sink) : void 0;
2726
2743
  }, [controller]);
2727
2744
  return /* @__PURE__ */ jsx(
2728
2745
  "div",
@@ -2780,7 +2797,7 @@ function EditableRegion({ block, region, label, id, placeholder, className }) {
2780
2797
  const { inline, decorations, placeholder: shown } = useEditorState(controller, select, samePainted);
2781
2798
  useIsomorphicLayoutEffect(() => {
2782
2799
  const host = ref.current;
2783
- return host === null ? void 0 : controller.registry.register(block, region, host);
2800
+ return host ? controller.registry.register(block, region, host) : void 0;
2784
2801
  }, [controller, block, region]);
2785
2802
  useIsomorphicLayoutEffect(() => {
2786
2803
  controller.renderHost(block, region);
@@ -2831,7 +2848,7 @@ var keepFocus = (event) => event.preventDefault();
2831
2848
 
2832
2849
  // src/view/react/TaskCheckbox.tsx
2833
2850
  import { jsx as jsx4 } from "react/jsx-runtime";
2834
- function TaskCheckbox({ block, controller, label = "Task", labelledBy }) {
2851
+ function TaskCheckbox({ block, controller, label, labelledBy }) {
2835
2852
  const checked = block.attrs.checked === true;
2836
2853
  const flip2 = flipCommand(block);
2837
2854
  const readOnly = useReadOnly(controller);
@@ -2842,7 +2859,7 @@ function TaskCheckbox({ block, controller, label = "Task", labelledBy }) {
2842
2859
  role: "checkbox",
2843
2860
  "aria-checked": checked,
2844
2861
  "aria-readonly": readOnly ? "true" : void 0,
2845
- "aria-label": label,
2862
+ "aria-label": firstNamed(label, "Task"),
2846
2863
  "aria-labelledby": labelledBy,
2847
2864
  className: "quoin-task-box",
2848
2865
  contentEditable: false,
@@ -3051,7 +3068,7 @@ var BlockShell = memo(function BlockShell2({ block, renderers }) {
3051
3068
  const hidden = status === "hidden";
3052
3069
  useIsomorphicLayoutEffect(() => {
3053
3070
  const element = ref.current;
3054
- return hidden || element === null ? void 0 : controller.registerBlockElement(block.id, element);
3071
+ return hidden || !element ? void 0 : controller.registerBlockElement(block.id, element);
3055
3072
  }, [controller, block.id, hidden]);
3056
3073
  if (hidden) return null;
3057
3074
  const Renderer = rendererFor(renderers, block.type);
@@ -3214,7 +3231,7 @@ function EditorView({
3214
3231
  const blockIdScope = useId();
3215
3232
  const blocks = useEditorState(controller, (state) => state.doc.blocks);
3216
3233
  const shells = useBlockElements(blocks, renderers);
3217
- useIsomorphicLayoutEffect(() => root.current === null ? void 0 : controller.attach(root.current), [controller]);
3234
+ useIsomorphicLayoutEffect(() => root.current ? controller.attach(root.current) : void 0, [controller]);
3218
3235
  return /* @__PURE__ */ jsx13(QuoinEditorContext.Provider, { value: controller, children: /* @__PURE__ */ jsxs3(
3219
3236
  "div",
3220
3237
  {
@@ -3224,7 +3241,7 @@ function EditorView({
3224
3241
  role: "group",
3225
3242
  "aria-label": label,
3226
3243
  "aria-describedby": hintId,
3227
- onFocus: (event) => focusOwners.set(event.target, controller),
3244
+ onFocusCapture: (event) => focusOwners.set(event.target, controller),
3228
3245
  children: [
3229
3246
  /* @__PURE__ */ jsx13(BlockDomIdScope.Provider, { value: blockIdScope, children: /* @__PURE__ */ jsx13(UnsupportedBlockLabel.Provider, { value: unsupportedBlockLabel, children: /* @__PURE__ */ jsx13(BlockPlaceholderContext.Provider, { value: blockPlaceholder, children: blocks.length === 0 ? /* @__PURE__ */ jsx13(EmptyDocumentHost, { placeholder, label: paragraphLabel }) : shells }) }) }),
3230
3247
  children,
@@ -3262,6 +3279,7 @@ export {
3262
3279
  NATIVE_INTERACTION,
3263
3280
  useIsomorphicLayoutEffect,
3264
3281
  onBlock,
3282
+ listen,
3265
3283
  createAutoScroll,
3266
3284
  hostKey,
3267
3285
  regionInline,
@@ -3283,4 +3301,4 @@ export {
3283
3301
  BlockShell,
3284
3302
  EditorView
3285
3303
  };
3286
- //# sourceMappingURL=chunk-ZS2WA357.js.map
3304
+ //# sourceMappingURL=chunk-EPARJI4V.js.map