quoin-editor 2.0.4 → 2.1.0

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 (215) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/MIGRATION.md +1 -1
  3. package/README.md +14 -13
  4. package/dist/ai.cjs +124 -94
  5. package/dist/ai.d.cts +7 -0
  6. package/dist/ai.d.ts +7 -0
  7. package/dist/ai.js +50 -20
  8. package/dist/ai.js.map +1 -1
  9. package/dist/catalogue.cjs +28 -26
  10. package/dist/catalogue.js +19 -17
  11. package/dist/catalogue.js.map +1 -1
  12. package/dist/{chunk-JGEDJYIV.cjs → chunk-2FUWXPPC.cjs} +92 -98
  13. package/dist/{chunk-NHNW5DK3.js → chunk-3F76QQ65.js} +6 -6
  14. package/dist/{chunk-NHNW5DK3.js.map → chunk-3F76QQ65.js.map} +1 -1
  15. package/dist/{chunk-DBOZFNWU.js → chunk-3QYFAAQR.js} +3 -3
  16. package/dist/{chunk-DBOZFNWU.js.map → chunk-3QYFAAQR.js.map} +1 -1
  17. package/dist/{chunk-I7X7B3WD.cjs → chunk-4JDRDPLC.cjs} +17 -8
  18. package/dist/{chunk-EBSDPHPS.cjs → chunk-4UFWFV43.cjs} +1060 -719
  19. package/dist/{chunk-LM3DHROX.cjs → chunk-5AUIA4B3.cjs} +2 -2
  20. package/dist/{chunk-3INFNIGN.cjs → chunk-5H3BB5VJ.cjs} +131 -78
  21. package/dist/{chunk-DJU25PFC.cjs → chunk-5L2NSIHZ.cjs} +11 -11
  22. package/dist/{chunk-W376L2GM.js → chunk-6Y7JAWYY.js} +8 -8
  23. package/dist/chunk-6Y7JAWYY.js.map +1 -0
  24. package/dist/{chunk-UDBLZILE.js → chunk-ATKDXQEY.js} +12 -7
  25. package/dist/{chunk-UDBLZILE.js.map → chunk-ATKDXQEY.js.map} +1 -1
  26. package/dist/{chunk-A2IQHMIH.js → chunk-BE2SYPK5.js} +49 -54
  27. package/dist/chunk-BE2SYPK5.js.map +1 -0
  28. package/dist/{chunk-PURYVDC3.cjs → chunk-CFICD2JP.cjs} +21 -16
  29. package/dist/{chunk-3HW3WRYC.cjs → chunk-CSIUXYRU.cjs} +2 -2
  30. package/dist/{chunk-N7BSFDDM.cjs → chunk-DBKL524I.cjs} +23 -23
  31. package/dist/{chunk-XE3IYW5B.js → chunk-DEFYFIWW.js} +90 -37
  32. package/dist/chunk-DEFYFIWW.js.map +1 -0
  33. package/dist/{chunk-7E43TURF.cjs → chunk-ECI3PSMS.cjs} +7 -7
  34. package/dist/{chunk-4G645EYO.js → chunk-F73QEF7E.js} +5 -5
  35. package/dist/{chunk-4G645EYO.js.map → chunk-F73QEF7E.js.map} +1 -1
  36. package/dist/{chunk-KHRVCTQQ.cjs → chunk-FUT7XLMP.cjs} +61 -74
  37. package/dist/{chunk-7J63427U.cjs → chunk-GQSBOBOM.cjs} +375 -320
  38. package/dist/{chunk-LU3T3JB4.js → chunk-HPNSQWRD.js} +15 -28
  39. package/dist/chunk-HPNSQWRD.js.map +1 -0
  40. package/dist/{chunk-7Y4B7NHO.js → chunk-I34BFOLL.js} +18 -11
  41. package/dist/chunk-I34BFOLL.js.map +1 -0
  42. package/dist/{chunk-AJT54OMZ.js → chunk-IFRXEFQH.js} +9 -15
  43. package/dist/chunk-IFRXEFQH.js.map +1 -0
  44. package/dist/{chunk-YYW33WUL.cjs → chunk-K3XWVRL4.cjs} +8 -8
  45. package/dist/{chunk-LSI4RMTY.js → chunk-L5L6YNLT.js} +3 -3
  46. package/dist/{chunk-LSI4RMTY.js.map → chunk-L5L6YNLT.js.map} +1 -1
  47. package/dist/{chunk-2BPXVQBP.js → chunk-MO4UMXMT.js} +238 -86
  48. package/dist/chunk-MO4UMXMT.js.map +1 -0
  49. package/dist/{chunk-2QKFRKOP.cjs → chunk-N25EH2GZ.cjs} +351 -205
  50. package/dist/{chunk-CSPCDVCT.js → chunk-NCV2ML25.js} +3 -3
  51. package/dist/{chunk-CSPCDVCT.js.map → chunk-NCV2ML25.js.map} +1 -1
  52. package/dist/{chunk-NUQ64S5B.cjs → chunk-OJSKSQTL.cjs} +26 -26
  53. package/dist/chunk-PIWMU4BV.js +9 -0
  54. package/dist/chunk-PIWMU4BV.js.map +1 -0
  55. package/dist/chunk-QFGWSFOI.cjs +10 -0
  56. package/dist/{chunk-GPTJYWGS.js → chunk-RNBLVGWY.js} +3 -3
  57. package/dist/{chunk-GPTJYWGS.js.map → chunk-RNBLVGWY.js.map} +1 -1
  58. package/dist/{chunk-5RBMZGKV.js → chunk-TL2MJOWM.js} +325 -57
  59. package/dist/chunk-TL2MJOWM.js.map +1 -0
  60. package/dist/{chunk-YEDPBYO5.cjs → chunk-UDQ52EEC.cjs} +4 -4
  61. package/dist/{chunk-EIWPJWY3.js → chunk-UE2NQPNG.js} +5 -5
  62. package/dist/{chunk-EIWPJWY3.js.map → chunk-UE2NQPNG.js.map} +1 -1
  63. package/dist/{chunk-BE2YHZXA.cjs → chunk-ULV3SCYP.cjs} +26 -15
  64. package/dist/{chunk-WDBFGX3U.cjs → chunk-VTTMJGWP.cjs} +72 -77
  65. package/dist/{chunk-556PFYES.js → chunk-WK4UGDZN.js} +290 -235
  66. package/dist/chunk-WK4UGDZN.js.map +1 -0
  67. package/dist/{chunk-JZF6UQH5.cjs → chunk-WMKA37NJ.cjs} +12 -12
  68. package/dist/{chunk-F2ZK6Z52.js → chunk-Y26F2X4E.js} +3 -3
  69. package/dist/{chunk-F2ZK6Z52.js.map → chunk-Y26F2X4E.js.map} +1 -1
  70. package/dist/{chunk-FK7EBZPX.cjs → chunk-Z5EEDCRI.cjs} +549 -276
  71. package/dist/{chunk-G6NBQYMM.js → chunk-ZGFZRVQA.js} +817 -478
  72. package/dist/chunk-ZGFZRVQA.js.map +1 -0
  73. package/dist/{chunk-QLVX7MPS.js → chunk-ZQF45LA4.js} +19 -8
  74. package/dist/chunk-ZQF45LA4.js.map +1 -0
  75. package/dist/comments.cjs +127 -65
  76. package/dist/comments.d.cts +35 -2
  77. package/dist/comments.d.ts +35 -2
  78. package/dist/comments.js +73 -12
  79. package/dist/comments.js.map +1 -1
  80. package/dist/{diagram-extension-22x_njXB.d.ts → diagram-extension-BMlh8GCw.d.ts} +1 -1
  81. package/dist/{diagram-extension-C_FSkoj9.d.cts → diagram-extension-gmndUpti.d.cts} +1 -1
  82. package/dist/diagram.cjs +10 -9
  83. package/dist/diagram.d.cts +2 -2
  84. package/dist/diagram.d.ts +2 -2
  85. package/dist/diagram.js +7 -6
  86. package/dist/diff.cjs +25 -25
  87. package/dist/diff.js +3 -3
  88. package/dist/docx.cjs +31 -30
  89. package/dist/docx.js +5 -4
  90. package/dist/docx.js.map +1 -1
  91. package/dist/embed.cjs +10 -9
  92. package/dist/embed.js +8 -7
  93. package/dist/{emoji-extension-Dk5IQLZf.d.cts → emoji-extension-DD9CQTQj.d.cts} +1 -1
  94. package/dist/{emoji-extension-C832oGeT.d.ts → emoji-extension-U_PWZ2fX.d.ts} +1 -1
  95. package/dist/emoji.cjs +10 -9
  96. package/dist/emoji.d.cts +2 -2
  97. package/dist/emoji.d.ts +2 -2
  98. package/dist/emoji.js +7 -6
  99. package/dist/engine.cjs +58 -58
  100. package/dist/engine.d.cts +3 -3
  101. package/dist/engine.d.ts +3 -3
  102. package/dist/engine.js +3 -3
  103. package/dist/{find-extension-DmK9_N81.d.ts → find-extension-BGlqooZi.d.ts} +1 -1
  104. package/dist/{find-extension-BfruAPLi.d.cts → find-extension-BPnAJ8bY.d.cts} +1 -1
  105. package/dist/find.cjs +11 -10
  106. package/dist/find.d.cts +1 -1
  107. package/dist/find.d.ts +1 -1
  108. package/dist/find.js +7 -6
  109. package/dist/headless.cjs +70 -69
  110. package/dist/headless.d.cts +33 -10
  111. package/dist/headless.d.ts +33 -10
  112. package/dist/headless.js +5 -4
  113. package/dist/highlight.cjs +7 -6
  114. package/dist/highlight.js +6 -5
  115. package/dist/highlight.js.map +1 -1
  116. package/dist/{index-3fYvwqUZ.d.cts → index-DN7vRKFw.d.cts} +1 -1
  117. package/dist/{index-CgxnzCO5.d.ts → index-DyIYI3PM.d.ts} +1 -1
  118. package/dist/index.cjs +82 -81
  119. package/dist/index.d.cts +19 -12
  120. package/dist/index.d.ts +19 -12
  121. package/dist/index.js +6 -5
  122. package/dist/{labels-CiCxj2jP.d.cts → labels-BJORhN93.d.ts} +10 -5
  123. package/dist/{labels-BhRJYo46.d.ts → labels-CVYJ2-1X.d.cts} +10 -5
  124. package/dist/locale-ar.cjs +10 -0
  125. package/dist/locale-ar.d.cts +1 -1
  126. package/dist/locale-ar.d.ts +1 -1
  127. package/dist/locale-ar.js +10 -0
  128. package/dist/locale-ar.js.map +1 -1
  129. package/dist/locale-de.cjs +4 -0
  130. package/dist/locale-de.d.cts +1 -1
  131. package/dist/locale-de.d.ts +1 -1
  132. package/dist/locale-de.js +4 -0
  133. package/dist/locale-de.js.map +1 -1
  134. package/dist/locale-es.cjs +4 -0
  135. package/dist/locale-es.d.cts +1 -1
  136. package/dist/locale-es.d.ts +1 -1
  137. package/dist/locale-es.js +4 -0
  138. package/dist/locale-es.js.map +1 -1
  139. package/dist/locale-fr.cjs +4 -0
  140. package/dist/locale-fr.d.cts +1 -1
  141. package/dist/locale-fr.d.ts +1 -1
  142. package/dist/locale-fr.js +4 -0
  143. package/dist/locale-fr.js.map +1 -1
  144. package/dist/locale-ja.cjs +4 -0
  145. package/dist/locale-ja.d.cts +1 -1
  146. package/dist/locale-ja.d.ts +1 -1
  147. package/dist/locale-ja.js +4 -0
  148. package/dist/locale-ja.js.map +1 -1
  149. package/dist/locale-pt.cjs +4 -0
  150. package/dist/locale-pt.d.cts +1 -1
  151. package/dist/locale-pt.d.ts +1 -1
  152. package/dist/locale-pt.js +4 -0
  153. package/dist/locale-pt.js.map +1 -1
  154. package/dist/locale-zh.cjs +4 -0
  155. package/dist/locale-zh.d.cts +1 -1
  156. package/dist/locale-zh.d.ts +1 -1
  157. package/dist/locale-zh.js +4 -0
  158. package/dist/locale-zh.js.map +1 -1
  159. package/dist/math.cjs +11 -10
  160. package/dist/math.js +9 -8
  161. package/dist/mention.cjs +11 -10
  162. package/dist/mention.js +9 -8
  163. package/dist/{node-reveal-DY6bimv3.d.cts → node-reveal-Be7Xa0BL.d.cts} +1 -1
  164. package/dist/{node-reveal-BnFcnHhz.d.ts → node-reveal-CftIEqF_.d.ts} +1 -1
  165. package/dist/palette-DuIFHYHc.d.cts +10 -0
  166. package/dist/palette-DuIFHYHc.d.ts +10 -0
  167. package/dist/presence.cjs +39 -38
  168. package/dist/presence.js +8 -7
  169. package/dist/presence.js.map +1 -1
  170. package/dist/source.cjs +10 -9
  171. package/dist/source.d.cts +1 -1
  172. package/dist/source.d.ts +1 -1
  173. package/dist/source.js +6 -5
  174. package/dist/source.js.map +1 -1
  175. package/dist/{stats-extension-Dmw0Ujxe.d.ts → stats-extension-Bbpr593p.d.ts} +1 -1
  176. package/dist/{stats-extension-D5HySF0a.d.cts → stats-extension-D7FaeydW.d.cts} +1 -1
  177. package/dist/stats.cjs +12 -10
  178. package/dist/stats.d.cts +2 -2
  179. package/dist/stats.d.ts +2 -2
  180. package/dist/stats.js +9 -7
  181. package/dist/styles.css +1 -1
  182. package/dist/{table-extension-7LkLNK6Q.d.cts → table-extension-DNijjmxV.d.cts} +1 -1
  183. package/dist/{table-extension-DEpV0DnP.d.ts → table-extension-Dp6FYGPh.d.ts} +1 -1
  184. package/dist/table.cjs +26 -25
  185. package/dist/table.d.cts +4 -3
  186. package/dist/table.d.ts +4 -3
  187. package/dist/table.js +7 -6
  188. package/dist/{toc-extension-Dvh37bWQ.d.cts → toc-extension-BGEVAmSY.d.cts} +1 -1
  189. package/dist/{toc-extension-SVckrFmb.d.ts → toc-extension-DZIe40eV.d.ts} +1 -1
  190. package/dist/toc.cjs +10 -9
  191. package/dist/toc.d.cts +2 -2
  192. package/dist/toc.d.ts +2 -2
  193. package/dist/toc.js +7 -6
  194. package/dist/{types-DMuuDBVh.d.ts → types-Byu2a9qk.d.ts} +6 -1
  195. package/dist/{types-Bzhq5AXj.d.cts → types-DdDlCyyZ.d.cts} +6 -1
  196. package/dist/view.cjs +4 -4
  197. package/dist/view.js +2 -2
  198. package/dist/yjs.cjs +121 -121
  199. package/dist/yjs.d.cts +2 -2
  200. package/dist/yjs.d.ts +2 -2
  201. package/dist/yjs.js +5 -5
  202. package/package.json +4 -3
  203. package/dist/chunk-2BPXVQBP.js.map +0 -1
  204. package/dist/chunk-556PFYES.js.map +0 -1
  205. package/dist/chunk-5RBMZGKV.js.map +0 -1
  206. package/dist/chunk-7Y4B7NHO.js.map +0 -1
  207. package/dist/chunk-A2IQHMIH.js.map +0 -1
  208. package/dist/chunk-AJT54OMZ.js.map +0 -1
  209. package/dist/chunk-G6NBQYMM.js.map +0 -1
  210. package/dist/chunk-LU3T3JB4.js.map +0 -1
  211. package/dist/chunk-QLVX7MPS.js.map +0 -1
  212. package/dist/chunk-W376L2GM.js.map +0 -1
  213. package/dist/chunk-XE3IYW5B.js.map +0 -1
  214. package/dist/palette-BrX-hEd-.d.cts +0 -4
  215. package/dist/palette-BrX-hEd-.d.ts +0 -4
@@ -1,5 +1,5 @@
1
- import { diffSequences } from './chunk-CSPCDVCT.js';
2
- import { ALERT_TONES, newId, requireBlockIndex, text, indexOfBlock, compareRegionNames, inlineLength, replaceBlocks, replaceInline, specFor, blockById, marksAt, sliceInline, updateBlock, createDoc, nodeLength, sanitizeHref, createBlockCodec, createSchema, documentNodes, blockPlainText, engineBlocksOf, isPaletteColor, coreAtomSpecs, coreMarkSpecs, coreBlockSpecs, sameValue, sameMark, inlineText, equalInline, removeMark, addMark, sameMarkSet, atom, hasMark, removeMarkRange, startsHtmlBlock, isRecord, fromMarkdown, isQuoinType, writtenAttrs, parseLine, serializeInline, sameItems, orderedStart, MAX_MARKER_NUMBER, parseInline, normalizeInline, str, linkClose, inlinePlainText, cellKey, PALETTE, addMarkRange } from './chunk-7Y4B7NHO.js';
1
+ import { diffSequences } from './chunk-NCV2ML25.js';
2
+ import { ALERT_TONES, newId, requireBlockIndex, text, indexOfBlock, compareRegionNames, inlineLength, replaceBlocks, replaceInline, specFor, blockById, marksAt, sliceInline, updateBlock, cellKey, createDoc, nodeLength, sanitizeHref, createBlockCodec, createSchema, documentNodes, blockPlainText, engineBlocksOf, isPaletteColor, coreAtomSpecs, coreMarkSpecs, coreBlockSpecs, sameValue, sameMark, inlineText, equalInline, removeMark, addMark, sameMarkSet, atom, hasMark, removeMarkRange, startsHtmlBlock, isRecord, fromMarkdown, isQuoinType, writtenAttrs, parseLine, serializeInline, sameItems, orderedStart, MAX_MARKER_NUMBER, parseInline, normalizeInline, str, linkClose, inlinePlainText, rangeHasMark, PALETTE, addMarkRange } from './chunk-I34BFOLL.js';
3
3
 
4
4
  // src/engine/transform/step.ts
5
5
  var StepError = class extends Error {
@@ -720,6 +720,20 @@ function createPluginKey(name) {
720
720
  return { name };
721
721
  }
722
722
 
723
+ // src/engine/state/carry-selection.ts
724
+ function carrySelection(selection, map, before, after, origin) {
725
+ if (origin !== "remote" || selection.kind !== "text") return mapSelection(selection, map, before);
726
+ const { anchor, head } = selection;
727
+ const backward = isBackward(before, selection);
728
+ const [from, to] = backward ? [head, anchor] : [anchor, head];
729
+ const end = map(to, after.index.has(to.block) ? -1 : 1);
730
+ const mapped = isCollapsed(selection) ? end : map(from, 1);
731
+ const inside = after.index.has(mapped.block) && after.index.has(end.block);
732
+ const start = inside && comparePos(after, mapped, end) > 0 ? end : mapped;
733
+ if (start === from && end === to) return selection;
734
+ return backward ? textSelection(end, start) : textSelection(start, end);
735
+ }
736
+
723
737
  // src/engine/state/transaction.ts
724
738
  var foreignOrigins = ["remote", "reconcile", "history"];
725
739
  var UNFILTERED = "unfiltered";
@@ -781,7 +795,7 @@ var Transaction = class {
781
795
  step(step) {
782
796
  const { doc, map } = step.apply(this.#currentDoc);
783
797
  if (this.#currentSelection !== null) {
784
- this.#currentSelection = mapSelection(this.#currentSelection, map, this.#currentDoc);
798
+ this.#currentSelection = carrySelection(this.#currentSelection, map, this.#currentDoc, doc, this.origin);
785
799
  }
786
800
  this.#docList.push(this.#currentDoc);
787
801
  this.#stepList.push(step);
@@ -967,22 +981,53 @@ var blocksOf = (step) => {
967
981
  const { block, created, target = null, source = target } = fields(step);
968
982
  return typeof block === "string" ? [block, created?.id ?? block] : [target, source];
969
983
  };
970
- function rebaseItems(items, tr) {
971
- const kept = [];
972
- const touched = tr.steps.flatMap(blocksOf);
973
- const mirrors = /* @__PURE__ */ new Map();
974
- const through = (maps) => (pos, assoc = 1) => {
975
- for (let i = 0; i < maps.length; i++) {
976
- const [ahead, gone, put] = mirrors.get(maps[i]) ?? [];
984
+ function changedBlocks(before, after) {
985
+ const next = (doc, id) => doc.blocks[doc.index.get(id) + 1]?.id;
986
+ return [.../* @__PURE__ */ new Set([...before.index.keys(), ...after.index.keys()])].filter((id) => {
987
+ const [was, is] = [blockById(before, id), blockById(after, id)];
988
+ return !was || !is || !sameValue(was, is) || next(before, id) !== next(after, id);
989
+ });
990
+ }
991
+ function pairOf(step, inverse, rewritten) {
992
+ if (step.stepType === "splitBlock") {
993
+ const { block: block2, region: region2, created } = fields(step);
994
+ const side = (pos) => pos.block === block2 && pos.region === region2 ? -1 : pos.block === created.id ? 1 : 0;
995
+ return { recover: () => null, side };
996
+ }
997
+ if (inverse.stepType !== "replaceInline") return void 0;
998
+ const { block, region, from, to } = fields(inverse);
999
+ const put = fields(rewritten);
1000
+ const here = (pos) => pos.block === block && pos.region === region;
1001
+ return {
1002
+ recover(pos, assoc) {
977
1003
  const at = pos.offset - (assoc < 0 ? 1 : 0);
978
- const inside = gone?.block === pos.block && gone.region === pos.region && at >= gone.from && at < gone.to;
979
- const j = inside ? maps.indexOf(ahead, i) : -1;
980
- if (j < i) pos = maps[i](pos, assoc);
981
- else [pos, i] = [{ block: put.block, region: put.region, offset: pos.offset - gone.from + put.from }, j];
982
- }
983
- return pos;
1004
+ const offset = pos.offset - from + put.from;
1005
+ return here(pos) && at >= from && at < to ? { block: put.block, region: put.region, offset } : null;
1006
+ },
1007
+ side: (pos) => !here(pos) ? 0 : pos.offset <= from ? -1 : pos.offset >= to ? 1 : 0
984
1008
  };
985
- let [before, after, change] = [tr.before.doc, tr.doc, tr.maps];
1009
+ }
1010
+ var through = (links) => (pos, assoc = 1) => {
1011
+ for (let i = 0; i < links.length; i++) {
1012
+ const { map, pair, back } = links[i];
1013
+ if (pair && back) {
1014
+ const put = pair.recover(pos, assoc);
1015
+ const j = put ? links.indexOf(pair.ahead, i) : -1;
1016
+ if (j > i) {
1017
+ [pos, i] = [put, j];
1018
+ continue;
1019
+ }
1020
+ pair.now = pair.side(pos);
1021
+ }
1022
+ pos = map(pos, !back && pair?.now || assoc);
1023
+ }
1024
+ return pos;
1025
+ };
1026
+ function rebaseItems(items, tr) {
1027
+ const kept = [];
1028
+ const named = tr.steps.flatMap(blocksOf);
1029
+ const touched = named.includes(null) ? changedBlocks(tr.before.doc, tr.doc) : named;
1030
+ let [before, after, change] = [tr.before.doc, tr.doc, tr.maps.map((map) => ({ map }))];
986
1031
  items: for (const item of [...items].reverse()) {
987
1032
  const { selection } = item;
988
1033
  const caret = !selection ? [] : selection.kind === "node" ? [selection.block] : selection.kind === "text" ? [selection.anchor.block, selection.head.block] : [selection.anchor, selection.head];
@@ -998,16 +1043,12 @@ function rebaseItems(items, tr) {
998
1043
  if (!original) continue items;
999
1044
  if (!apart) {
1000
1045
  const inverse = step.invert(b);
1001
- const { map } = inverse.apply(original.doc);
1002
- back.unshift(map);
1003
- if (result && inverse.stepType === "replaceInline") {
1004
- mirrors.set(map, [result.map, fields(inverse), fields(rewritten)]);
1005
- }
1046
+ const pair = result ? pairOf(step, inverse, rewritten) : void 0;
1047
+ back.unshift({ map: inverse.apply(original.doc).map, pair, back: true });
1048
+ if (result) ahead.push(pair ? pair.ahead = { map: result.map, pair } : { map: result.map });
1006
1049
  }
1007
- if (result) {
1008
- [a, steps] = [result.doc, [...steps, rewritten]];
1009
- if (!apart) ahead.push(result.map);
1010
- } else steps = null;
1050
+ if (result) [a, steps] = [result.doc, [...steps, rewritten]];
1051
+ else steps = null;
1011
1052
  b = original.doc;
1012
1053
  }
1013
1054
  [before, after, change] = [b, steps ? a : after, [...back, ...change, ...steps ? ahead : []]];
@@ -1309,16 +1350,38 @@ function insertBlockAfter(type, attrs, options = {}) {
1309
1350
  };
1310
1351
  }
1311
1352
 
1353
+ // src/engine/blocks/table-cell.ts
1354
+ var CELL = /^cell:(\d+):(\d+)$/;
1355
+ function cellOf(region) {
1356
+ const match = CELL.exec(region);
1357
+ return match === null ? null : [Number(match[1]), Number(match[2])];
1358
+ }
1359
+ function cellsBetween(a, b) {
1360
+ const cells = [];
1361
+ for (let row = Math.min(a[0], b[0]); row <= Math.max(a[0], b[0]); row++) {
1362
+ for (let col = Math.min(a[1], b[1]); col <= Math.max(a[1], b[1]); col++) cells.push([row, col]);
1363
+ }
1364
+ return cells;
1365
+ }
1366
+
1312
1367
  // src/engine/commands/delete-range.ts
1313
1368
  function clear(tr, pos, start, end) {
1314
1369
  if (start < end) tr.step(replaceInlineStep(pos.block, pos.region, start, end, []));
1315
1370
  }
1371
+ function clearCells(tr, block, from, to) {
1372
+ const cells = cellsBetween(from, to).map((cell) => cellKey(...cell));
1373
+ for (const region of cells) clear(tr, { block: block.id, region}, 0, regionLength(block, region));
1374
+ return { block: block.id, region: cells[0], offset: 0 };
1375
+ }
1316
1376
  function deleteWithinBlock(tr, from, to) {
1317
1377
  if (from.region === to.region) {
1318
1378
  clear(tr, from, from.offset, to.offset);
1319
1379
  return from;
1320
1380
  }
1321
1381
  const block = tr.doc.blocks[requireBlockIndex(tr.doc, from.block)];
1382
+ const first = cellOf(from.region);
1383
+ const last = cellOf(to.region);
1384
+ if (first !== null && last !== null) return clearCells(tr, block, first, last);
1322
1385
  clear(tr, from, from.offset, regionLength(block, from.region));
1323
1386
  for (const region of Object.keys(block.regions)) {
1324
1387
  const between = compareRegionNames(from.region, region) < 0 && compareRegionNames(region, to.region) < 0;
@@ -1419,7 +1482,11 @@ function markExtent(inline, offset, type) {
1419
1482
 
1420
1483
  // src/engine/commands/storable-mark.ts
1421
1484
  function readsBack(inline) {
1422
- return equalInline(parseInline(serializeInline(inline)), normalizeInline(inline));
1485
+ try {
1486
+ return equalInline(parseInline(serializeInline(inline)), normalizeInline(inline));
1487
+ } catch {
1488
+ return false;
1489
+ }
1423
1490
  }
1424
1491
  function safeLink(mark) {
1425
1492
  const href = mark.attrs?.href;
@@ -1917,6 +1984,38 @@ function typographyRules(options = {}) {
1917
1984
  ];
1918
1985
  }
1919
1986
 
1987
+ // src/engine/clipboard/html-class-rules.ts
1988
+ var RULE = /([^{}]+)\{([^{}]*)\}/g;
1989
+ var COMMENT = /\/\*[\s\S]*?\*\/|<!--|-->/g;
1990
+ var CLASS_SELECTOR = /^(?:[a-z][\w-]*)?\.[a-z_][\w-]*$/i;
1991
+ function inlineClassRules(body) {
1992
+ const sheets = /* @__PURE__ */ new Map();
1993
+ for (const sheet of Array.from(body.ownerDocument.querySelectorAll("style"))) {
1994
+ for (const [, selectors, declarations] of (sheet.textContent ?? "").replace(COMMENT, "").matchAll(RULE)) {
1995
+ for (const selector of selectors.split(",").map((part) => part.trim())) {
1996
+ if (!CLASS_SELECTOR.test(selector)) continue;
1997
+ for (const element of Array.from(body.querySelectorAll(selector))) {
1998
+ sheets.set(element, `${sheets.get(element) ?? ""}${declarations};`);
1999
+ }
2000
+ }
2001
+ }
2002
+ }
2003
+ for (const [element, rules] of sheets) element.setAttribute("style", rules + (element.getAttribute("style") ?? ""));
2004
+ }
2005
+
2006
+ // src/engine/clipboard/html-task-box.ts
2007
+ var BALLOT_BOX = /^([☐☑☒])\s*/;
2008
+ var UNCHECKED = "\u2610";
2009
+ var BOXABLE = /* @__PURE__ */ new Set(["paragraph", "bullet", "ordered"]);
2010
+ function boxedTask(attrs, content) {
2011
+ const box = BOXABLE.has(String(attrs.kind)) ? BALLOT_BOX.exec(inlineText(content)) : null;
2012
+ if (box === null) return { attrs, content };
2013
+ return {
2014
+ attrs: { kind: "task", checked: box[1] !== UNCHECKED },
2015
+ content: sliceInline(content, box[0].length, inlineLength(content))
2016
+ };
2017
+ }
2018
+
1920
2019
  // src/engine/clipboard/html-context.ts
1921
2020
  var PARAGRAPH2 = { kind: "paragraph" };
1922
2021
  var child = (ctx, patch = {}) => ({
@@ -1927,7 +2026,10 @@ var child = (ctx, patch = {}) => ({
1927
2026
  function emit(sink, type, indent2, attrs, regions) {
1928
2027
  sink.out.push({ id: sink.newId(), type, indent: indent2, attrs, regions });
1929
2028
  }
1930
- var emitText = (sink, indent2, attrs, content) => emit(sink, "MARKDOWN", indent2, attrs, { text: content });
2029
+ function emitText(sink, indent2, attrs, content) {
2030
+ const task = boxedTask(attrs, content);
2031
+ emit(sink, "MARKDOWN", indent2, task.attrs, { text: task.content });
2032
+ }
1931
2033
 
1932
2034
  // src/engine/clipboard/html-dom.ts
1933
2035
  var ELEMENT_NODE = 1;
@@ -2105,14 +2207,14 @@ function isItalicStyle(styles) {
2105
2207
  }
2106
2208
  var PRESERVING = /* @__PURE__ */ new Set(["pre", "pre-wrap", "break-spaces"]);
2107
2209
  var COLLAPSING = /* @__PURE__ */ new Set(["normal", "nowrap", "pre-line"]);
2108
- var MONOSPACE = /\b(?:monospace|menlo|monaco|consolas|courier)\b/;
2210
+ var MONOSPACE = /\bmono\b|monospace|menlo|monaco|consol|courier/;
2109
2211
  function keepsWhitespace(styles) {
2110
2212
  const value = styles.get("white-space");
2111
2213
  if (value === void 0) return null;
2112
2214
  if (PRESERVING.has(value)) return true;
2113
2215
  return COLLAPSING.has(value) ? false : null;
2114
2216
  }
2115
- var isMonospace = (styles) => MONOSPACE.test(styles.get("font-family") ?? "");
2217
+ var isMonospace = (styles) => MONOSPACE.test(styles.get("font-family") ?? styles.get("font") ?? "");
2116
2218
  function hasDecoration(styles, line2) {
2117
2219
  return (styles.get("text-decoration") ?? "").includes(line2) || (styles.get("text-decoration-line") ?? "").includes(line2);
2118
2220
  }
@@ -2136,8 +2238,28 @@ function fromFunction(args) {
2136
2238
  if ([r, g, b, alpha].some(Number.isNaN)) return null;
2137
2239
  return { rgb: [r, g, b], alpha };
2138
2240
  }
2241
+ var NAMED = new Map(
2242
+ Object.entries({
2243
+ black: "#000",
2244
+ white: "#fff",
2245
+ red: "#f00",
2246
+ lime: "#0f0",
2247
+ blue: "#00f",
2248
+ yellow: "#ff0",
2249
+ aqua: "#0ff",
2250
+ fuchsia: "#f0f",
2251
+ maroon: "#800000",
2252
+ green: "#008000",
2253
+ navy: "#000080",
2254
+ olive: "#808000",
2255
+ purple: "#800080",
2256
+ teal: "#008080",
2257
+ gray: "#808080",
2258
+ silver: "#c0c0c0"
2259
+ })
2260
+ );
2139
2261
  function parseColor(css) {
2140
- const value = css.trim();
2262
+ const value = NAMED.get(css.trim()) ?? css.trim();
2141
2263
  const hex = HEX.exec(value);
2142
2264
  const functional = FUNCTION.exec(value);
2143
2265
  const parsed = hex ? fromHex(hex[1]) : functional ? fromFunction(functional[1]) : null;
@@ -2193,9 +2315,14 @@ function highlightMark(element) {
2193
2315
  const color = element.getAttribute("data-color") ?? "";
2194
2316
  return isPaletteColor(color) ? { type: "highlight", attrs: { color } } : { type: "highlight" };
2195
2317
  }
2318
+ var CODE_TAGS = /* @__PURE__ */ new Set(["code", "kbd", "tt", "samp"]);
2319
+ function fontAttributes(element) {
2320
+ return `color:${element.getAttribute("color") ?? ""};font-family:${element.getAttribute("face") ?? ""};`;
2321
+ }
2196
2322
  function elementMarks(element, inherited) {
2197
2323
  const tag = tagName(element);
2198
- const styles = parseStyle(element.getAttribute("style"));
2324
+ const pageStyle = isFragmentRoot(element);
2325
+ const styles = parseStyle((tag === "font" ? fontAttributes(element) : "") + (element.getAttribute("style") ?? ""));
2199
2326
  let marks = inherited;
2200
2327
  const add = (mark) => {
2201
2328
  marks = addMark(marks, mark);
@@ -2213,15 +2340,15 @@ function elementMarks(element, inherited) {
2213
2340
  if (tag === "s" || tag === "del" || tag === "strike" || hasDecoration(styles, "line-through")) {
2214
2341
  add({ type: "strike" });
2215
2342
  }
2216
- if (tag === "code" || tag === "kbd") add({ type: "code" });
2343
+ if (CODE_TAGS.has(tag) || !pageStyle && isMonospace(styles)) add({ type: "code" });
2217
2344
  const align = verticalAlign(styles);
2218
2345
  if (tag === "sub" || align === "sub") add({ type: "sub" });
2219
2346
  if (tag === "sup" || align === "super") add({ type: "sup" });
2220
2347
  if (tag === "mark") add(highlightMark(element));
2221
- const pageColors = isFragmentRoot(element);
2222
- const color = linked2 || pageColors ? null : nearestPaletteColor(styles.get("color") ?? "", "text");
2348
+ const color = linked2 || pageStyle ? null : nearestPaletteColor(styles.get("color") ?? "", "text");
2223
2349
  if (color !== null) add({ type: "color", attrs: { color } });
2224
- const background = pageColors ? null : nearestPaletteColor(styles.get("background-color") ?? "", "background");
2350
+ const fill = styles.get("background-color") ?? styles.get("background") ?? "";
2351
+ const background = pageStyle ? null : nearestPaletteColor(fill, "background");
2225
2352
  if (background !== null) add({ type: "background", attrs: { color: background } });
2226
2353
  return marks;
2227
2354
  }
@@ -2283,7 +2410,7 @@ function append(acc, raw, marks, preformatted) {
2283
2410
  function finish({ pieces }) {
2284
2411
  while (pieces.length > 0) {
2285
2412
  const last = pieces[pieces.length - 1];
2286
- const trimmed2 = last.text.replace(/[ \n]+$/, "");
2413
+ const trimmed2 = last.text.replace(/[ \n\u00a0]+$/, "");
2287
2414
  if (trimmed2 === "") pieces.pop();
2288
2415
  else {
2289
2416
  pieces[pieces.length - 1] = { ...last, text: trimmed2 };
@@ -2316,6 +2443,63 @@ function inlineFromNodes(nodes, style) {
2316
2443
  return finish(acc);
2317
2444
  }
2318
2445
 
2446
+ // src/engine/clipboard/html-font-size.ts
2447
+ var LENGTH = /(\d*\.?\d+)(px|pt)/;
2448
+ var MEDIUM_PX = 16;
2449
+ var LEVELS = [
2450
+ [1.8, 1],
2451
+ [1.4, 2],
2452
+ [1.15, 3]
2453
+ ];
2454
+ function declaredSize(element) {
2455
+ const styles = parseStyle(element.getAttribute("style"));
2456
+ const length = LENGTH.exec(styles.get("font-size") ?? styles.get("font") ?? "");
2457
+ return length && Number(length[1]) * (length[2] === "pt" ? 4 / 3 : 1);
2458
+ }
2459
+ function sizeOf(element, known) {
2460
+ const chain = [];
2461
+ let size;
2462
+ for (let at = element; at !== null && size == null; at = at.parentElement) {
2463
+ chain.push(at);
2464
+ size = known.get(at) ?? declaredSize(at);
2465
+ }
2466
+ const resolved = size ?? MEDIUM_PX;
2467
+ for (const at of chain) known.set(at, resolved);
2468
+ return resolved;
2469
+ }
2470
+ function eachText(root, visit2) {
2471
+ const pending = [root];
2472
+ for (let node = pending.pop(); node !== void 0; node = pending.pop()) {
2473
+ if (node.nodeType === TEXT_NODE) visit2(node.nodeValue ?? "", node.parentElement ?? root);
2474
+ else if (isElement(node) && !isDropped(node) && !isMsoIgnored(node)) {
2475
+ for (let part = node.lastChild; part !== null; part = part.previousSibling) pending.push(part);
2476
+ }
2477
+ }
2478
+ }
2479
+ function bodySize(body, known) {
2480
+ const weights = /* @__PURE__ */ new Map([[MEDIUM_PX, 0]]);
2481
+ eachText(body, (text2, parent) => {
2482
+ const weight = text2.replace(/\s/g, "").length;
2483
+ if (weight === 0) return;
2484
+ const size = sizeOf(parent, known);
2485
+ weights.set(size, (weights.get(size) ?? 0) + weight);
2486
+ });
2487
+ return [...weights].reduce((most, entry) => entry[1] > most[1] ? entry : most)[0];
2488
+ }
2489
+ function sizedHeading(root) {
2490
+ const known = /* @__PURE__ */ new Map();
2491
+ let base;
2492
+ return (paragraph) => {
2493
+ let least = Infinity;
2494
+ eachText(paragraph, (text2, parent) => {
2495
+ if (/\S/.test(text2)) least = Math.min(least, sizeOf(parent, known));
2496
+ });
2497
+ if (least === Infinity) return null;
2498
+ const body = base ??= bodySize(root, known);
2499
+ return LEVELS.find(([ratio]) => least >= body * ratio)?.[1] ?? null;
2500
+ };
2501
+ }
2502
+
2319
2503
  // src/engine/clipboard/html-lists.ts
2320
2504
  var LIST_TAGS = /* @__PURE__ */ new Set(["ul", "ol"]);
2321
2505
  var MARKER_NUMBER = /^(\d+)[.)]$/;
@@ -2326,7 +2510,9 @@ function checkboxState(node) {
2326
2510
  return node.hasAttribute("checked");
2327
2511
  }
2328
2512
  if (hasClass(node, "checkbox-on")) return true;
2329
- return hasClass(node, "checkbox-off") ? false : null;
2513
+ if (hasClass(node, "checkbox-off")) return false;
2514
+ const box = node.getAttribute("role") === "checkbox" || node.getAttribute("aria-roledescription") === "checkbox";
2515
+ return box ? node.getAttribute("aria-checked") === "true" : null;
2330
2516
  }
2331
2517
  function takeCheckbox(nodes) {
2332
2518
  const at = nodes.findIndex((node) => checkboxState(node) !== null);
@@ -2334,20 +2520,26 @@ function takeCheckbox(nodes) {
2334
2520
  return { checked: checkboxState(nodes[at]), rest: nodes.filter((_, index) => index !== at) };
2335
2521
  }
2336
2522
  var isPlainWrapper = (node) => isElement(node) && ["p", "div"].includes(tagName(node)) && !hasBlockDescendant(node);
2523
+ var WORD_LEVELS = 9;
2524
+ function depthOf(item) {
2525
+ const level = Math.trunc(Number(item.getAttribute("data-aria-level"))) || 1;
2526
+ return Math.min(WORD_LEVELS, Math.max(1, level)) - 1;
2527
+ }
2337
2528
  function listItem(item, base, ctx, sink) {
2338
2529
  const own = takeCheckbox(Array.from(item.childNodes));
2339
2530
  const split = own.rest.findIndex(breaksRun);
2340
2531
  let content = inlineFromNodes(split < 0 ? own.rest : own.rest.slice(0, split), ctx);
2341
2532
  let rest = split < 0 ? [] : own.rest.slice(split);
2342
- let checked = own.checked;
2533
+ let checked = checkboxState(item) ?? own.checked;
2343
2534
  if (content.length === 0 && rest.length > 0 && isPlainWrapper(rest[0])) {
2344
2535
  const inner = takeCheckbox(Array.from(rest[0].childNodes));
2345
2536
  checked = checked ?? inner.checked;
2346
2537
  content = inlineFromNodes(inner.rest, ctx);
2347
2538
  rest = rest.slice(1);
2348
2539
  }
2349
- emitText(sink, ctx.indent, checked === null ? base : { kind: "task", checked }, content);
2350
- sink.walk(rest, child(ctx, { indent: ctx.indent + 1, run: PARAGRAPH2 }));
2540
+ const indent2 = ctx.indent + depthOf(item);
2541
+ emitText(sink, indent2, checked === null ? base : { kind: "task", checked }, content);
2542
+ sink.walk(rest, child(ctx, { indent: indent2 + 1, run: PARAGRAPH2 }));
2351
2543
  }
2352
2544
  function firstNumber(list2) {
2353
2545
  const start = Number.parseInt(list2.getAttribute("start") ?? "", 10);
@@ -2403,6 +2595,7 @@ function figure(element, ctx, sink) {
2403
2595
 
2404
2596
  // src/engine/clipboard/html-table.ts
2405
2597
  var SECTIONS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
2598
+ var MAX_SPAN = 1e3;
2406
2599
  function rowOf(tr, head) {
2407
2600
  return { cells: Array.from(tr.children).filter((cell) => ["td", "th"].includes(tagName(cell))), head };
2408
2601
  }
@@ -2417,15 +2610,33 @@ function tableRows(table) {
2417
2610
  }
2418
2611
  return rows;
2419
2612
  }
2613
+ var span = (cell, name) => Math.min(MAX_SPAN, Math.max(1, Number.parseInt(cell.getAttribute(name) ?? "", 10) || 1));
2614
+ function grid(rows) {
2615
+ const slots = rows.map(() => []);
2616
+ rows.forEach(({ cells }, r) => {
2617
+ let c = 0;
2618
+ for (const cell of cells) {
2619
+ while (slots[r][c] !== void 0) c++;
2620
+ const across = span(cell, "colspan");
2621
+ const down = Math.min(span(cell, "rowspan"), rows.length - r);
2622
+ for (let dr = 0; dr < down; dr++) {
2623
+ for (let dc = 0; dc < across; dc++) slots[r + dr][c + dc] = dr === 0 && dc === 0 ? cell : null;
2624
+ }
2625
+ c += across;
2626
+ }
2627
+ });
2628
+ return slots;
2629
+ }
2420
2630
  function tableBlock(table, ctx, sink) {
2421
2631
  const rows = tableRows(table);
2422
- const cols = rows.reduce((widest, row) => Math.max(widest, row.cells.length), 0);
2632
+ const slots = grid(rows);
2633
+ const cols = slots.reduce((widest, row) => Math.max(widest, row.length), 0);
2423
2634
  if (rows.length === 0 || cols === 0) return;
2424
2635
  const regions = {};
2425
- rows.forEach((row, r) => {
2636
+ slots.forEach((row, r) => {
2426
2637
  for (let c = 0; c < cols; c++) {
2427
- const cell = row.cells[c];
2428
- regions[cellKey(r, c)] = cell === void 0 ? [] : inlineFromNodes(cell.childNodes, ctx);
2638
+ const cell = row[c];
2639
+ regions[cellKey(r, c)] = cell ? inlineFromNodes(cell.childNodes, ctx) : [];
2429
2640
  }
2430
2641
  });
2431
2642
  const header = rows[0].head || rows[0].cells.some((cell) => tagName(cell) === "th");
@@ -2455,12 +2666,27 @@ function styledContext(element, outer) {
2455
2666
  const ctx = { ...outer, marks, preformatted: keeps ?? outer.preformatted };
2456
2667
  return { ctx, code: keeps === true && isMonospace(styles) };
2457
2668
  }
2669
+ function isBold(element, ctx) {
2670
+ const inline = inlineFromNodes(element.childNodes, ctx);
2671
+ return rangeHasMark(inline, 0, inlineLength(inline), "bold");
2672
+ }
2673
+ function headingLevel(element, tag, ctx, sink) {
2674
+ const named = HEADING.exec(tag);
2675
+ if (named) return Number(named[1]);
2676
+ if (element.getAttribute("role") === "heading") {
2677
+ return Math.min(6, Math.max(1, Math.trunc(Number(element.getAttribute("aria-level"))) || 2));
2678
+ }
2679
+ const paragraph = (tag === "p" || tag === "div") && ctx.run.kind === "paragraph" && !hasBlockDescendant(element);
2680
+ const level = paragraph ? sink.sizedHeading(element) : null;
2681
+ return level === 1 || level !== null && isBold(element, ctx) ? level : null;
2682
+ }
2458
2683
  function handleBlock(element, outer, sink) {
2459
2684
  const { ctx, code } = styledContext(element, outer);
2460
2685
  const tag = tagName(element);
2461
2686
  if (code && tag === "div") return codeBlock(element, ctx, sink);
2462
- const heading = HEADING.exec(tag);
2463
- if (heading) return sink.walk(element.childNodes, child(ctx, { run: { kind: "heading", level: Number(heading[1]) } }));
2687
+ if (tag === "p" && wordListItem(element, ctx, sink)) return;
2688
+ const level = headingLevel(element, tag, ctx, sink);
2689
+ if (level !== null) return sink.walk(element.childNodes, child(ctx, { run: { kind: "heading", level } }));
2464
2690
  switch (tag) {
2465
2691
  case "ul":
2466
2692
  case "ol":
@@ -2483,8 +2709,6 @@ function handleBlock(element, outer, sink) {
2483
2709
  return figure(element, ctx, sink);
2484
2710
  case "details":
2485
2711
  return details(element, ctx, sink);
2486
- case "p":
2487
- if (wordListItem(element, ctx, sink)) return;
2488
2712
  }
2489
2713
  sink.walk(element.childNodes, child(ctx));
2490
2714
  }
@@ -2510,7 +2734,13 @@ function walkNodes(nodes, ctx, sink) {
2510
2734
  flush();
2511
2735
  }
2512
2736
  function blocksFromBody(body, newId2) {
2513
- const sink = { out: [], newId: newId2, walk: (nodes, ctx) => walkNodes(nodes, ctx, sink) };
2737
+ inlineClassRules(body);
2738
+ const sink = {
2739
+ out: [],
2740
+ newId: newId2,
2741
+ sizedHeading: sizedHeading(body),
2742
+ walk: (nodes, ctx) => walkNodes(nodes, ctx, sink)
2743
+ };
2514
2744
  sink.walk(body.childNodes, { indent: 0, marks: [], run: PARAGRAPH2, preformatted: false, depth: 0 });
2515
2745
  return sink.out;
2516
2746
  }
@@ -2885,6 +3115,12 @@ function words(text2) {
2885
3115
  }
2886
3116
  return [...wordSegmenter.segment(text2)].filter((s) => s.isWordLike).map((s) => ({ start: s.index, end: s.index + s.segment.length }));
2887
3117
  }
3118
+ function graphemePrefix(text2, count2) {
3119
+ if (!graphemeSegmenter) return [...text2].slice(0, count2).join("");
3120
+ let seen = 0;
3121
+ for (const { index } of graphemeSegmenter.segment(text2)) if (seen++ === count2) return text2.slice(0, index);
3122
+ return text2;
3123
+ }
2888
3124
  function graphemeCount(text2) {
2889
3125
  return boundaries(text2).length - 1;
2890
3126
  }
@@ -3589,6 +3825,7 @@ function sliceText(slice, options) {
3589
3825
  const block = pieces.length === 1 ? stripComments(pieces[0]) : null;
3590
3826
  const region = block === null || !isTextFlow(schema, block) ? null : primaryRegion(schema, block);
3591
3827
  if (block !== null && region !== null) return inlinePlainText(block.regions[region] ?? [], schema);
3828
+ if (block?.type === "TABLE") return blockPlainText(block, schema);
3592
3829
  }
3593
3830
  const markdown = toMarkdown(slice.blocks, { schema, resolveAssetUrl: options.resolveAssetUrl, comments: false });
3594
3831
  return markdown.replace(/\n$/, "");
@@ -3601,6 +3838,32 @@ function sliceToClipboard(slice, options = {}) {
3601
3838
  };
3602
3839
  }
3603
3840
 
3841
+ // src/engine/clipboard/table-part.ts
3842
+ function tablePart(block, from, to) {
3843
+ const a = cellOf(from);
3844
+ const b = cellOf(to);
3845
+ if (a === null || b === null) return block;
3846
+ const cells = cellsBetween(a, b);
3847
+ const [top, left] = cells[0];
3848
+ const [bottom, right] = cells[cells.length - 1];
3849
+ const regions = {};
3850
+ for (const [row, col] of cells) regions[cellKey(row - top, col - left)] = block.regions[cellKey(row, col)] ?? [];
3851
+ const columns = (list2) => Array.isArray(list2) ? list2.slice(left, right + 1) : list2;
3852
+ const { attrs } = block;
3853
+ return {
3854
+ ...block,
3855
+ regions,
3856
+ attrs: {
3857
+ ...attrs,
3858
+ rows: bottom - top + 1,
3859
+ cols: right - left + 1,
3860
+ header: attrs.header !== false && top === 0,
3861
+ align: columns(attrs.align),
3862
+ widths: columns(attrs.widths)
3863
+ }
3864
+ };
3865
+ }
3866
+
3604
3867
  // src/engine/clipboard/extract-slice.ts
3605
3868
  function isFlowRegion(schema, block, region) {
3606
3869
  return isTextFlow(schema, block) && region === primaryRegion(schema, block);
@@ -3619,7 +3882,7 @@ function textBlocks({ doc, schema }, selection) {
3619
3882
  const end = requireBlockIndex(doc, to.block);
3620
3883
  const first = doc.blocks[start];
3621
3884
  if (start === end) {
3622
- if (from.region !== to.region) return [first];
3885
+ if (from.region !== to.region) return [tablePart(first, from.region, to.region)];
3623
3886
  return [insideOneRegion(schema, first, from.region, from.offset, to.offset)];
3624
3887
  }
3625
3888
  const last = doc.blocks[end];
@@ -3690,6 +3953,9 @@ function parseSliceJSON(json) {
3690
3953
  return { blocks, openStart, openEnd };
3691
3954
  }
3692
3955
 
3956
+ // src/engine/clipboard/slice.ts
3957
+ var PASTED_HTML = "pastedHTML";
3958
+
3693
3959
  // src/engine/clipboard/slice-from-clipboard.ts
3694
3960
  var isParagraph2 = (block) => block.type === "MARKDOWN" && parseLine(String(block.data.markdown ?? "")).kind === "paragraph";
3695
3961
  function openSlice(blocks, plainText2 = false) {
@@ -3713,7 +3979,8 @@ function textBlocks2(text2, makeId) {
3713
3979
  function htmlSlice(html, options) {
3714
3980
  if (html === void 0) return null;
3715
3981
  const parser = availableParser(options.parser);
3716
- return parser === null ? null : openSlice(fromHTML(html, { ...options, parser }));
3982
+ const slice = parser === null ? null : openSlice(fromHTML(html, { ...options, parser }));
3983
+ return slice && { ...slice, fromHTML: true };
3717
3984
  }
3718
3985
  function sliceFromClipboard(data, options = {}) {
3719
3986
  const fromJson = data.json === void 0 ? null : parseSliceJSON(data.json);
@@ -3722,6 +3989,7 @@ function sliceFromClipboard(data, options = {}) {
3722
3989
  if (fromHtml !== null) return fromHtml;
3723
3990
  return data.text === void 0 ? null : openSlice(textBlocks2(data.text, options.newId ?? newId), true);
3724
3991
  }
3992
+ var dispatchPaste = (slice, dispatch) => (tr) => dispatch(slice.fromHTML ? tr.setMeta(PASTED_HTML, true) : tr);
3725
3993
 
3726
3994
  // src/engine/commands/is-active.ts
3727
3995
  function hasAttrs(block, attrs) {
@@ -3986,10 +4254,10 @@ function createInternalEditor(options) {
3986
4254
  function paste(data, parser) {
3987
4255
  if (destroyed) return false;
3988
4256
  const { text: text2 } = data;
3989
- const ruled = text2 !== void 0 && resolved.pasteRules.some((rule) => rule.match(text2, state)?.(state, dispatch));
4257
+ const ruled = text2 !== void 0 && resolved.pasteRules.some((rule) => rule.match(text2, state, data)?.(state, dispatch));
3990
4258
  if (ruled) return true;
3991
4259
  const slice = sliceFromClipboard(data, { parser, newId: newId2 });
3992
- return slice !== null && insertSlice(slice, { newId: newId2 })(state, dispatch);
4260
+ return slice !== null && insertSlice(slice, { newId: newId2 })(state, dispatchPaste(slice, dispatch));
3993
4261
  }
3994
4262
  function copy() {
3995
4263
  const slice = sliceFromSelection(state, codec);
@@ -4050,6 +4318,6 @@ function createInternalEditor(options) {
4050
4318
  return editor;
4051
4319
  }
4052
4320
 
4053
- export { HISTORY_GROUP, HISTORY_PROVIDER, LINE_JOIN, LINE_SPLIT, Transaction, addMarkStep, applyTransaction, blockInputRules, blockRangeSelection, capIndents, caretMarks, commonPrefix, commonSuffix, comparePos, continuesEdit, coreExtensions, countBlock, countDoc, countText, createBlock, createEditor, createPluginKey, createState, defineExtension, deleteBackward, deleteBlocks, deleteForward, deleteRange, deleteSelection, deleteToLineEnd, deleteToLineStart, deleteWordBackward, deleteWordForward, descendantsEnd, detectMac, duplicateBlocks, editEnd, endOf, foreignOrigins, freshBlocks, fromHTML, getPluginState, graphemeCount, groupOf, headBlockId, hidingToggle, indent, insertBlockAfter, insertBlocksStep, insertHardBreak, insertMention, insertSlice, insertText, insertTextAt, insertTextWithRules, isActive, isClosedToggle, isCollapsed, isParagraph, isTextFlow, joinBlocksStep, keyName, mapSelection, markCoverage, markExtent, markInputRules, markRanges, moveBlocksDown, moveBlocksStep, moveBlocksTo, moveBlocksUp, movedBlockIds, nextGraphemeOffset, nodeSelection, normalizeKey, orderedRange, outdent, pasteAtCaret, pastedLink, prevGraphemeOffset, primaryRegion, rangeContent, redo, regionInline, regionLength, removeBlocksStep, removeMarkStep, replaceBlockStep, replaceDocStep, replaceInlineStep, runCommands, sameDoc, sameSelection, selectAll, selectedBlockIds, selectedBlockRange, selectionRange, setAttrs, setAttrsStep, setBlockColor, setBlockType, setIndentStep, setLink, setMark, setSelection, setTextAlign, sliceFromClipboard, sliceFromSelection, splitBlockStep, startOf, stepFromJSON, textSelection, toHTML, toMarkdown, toPlainText, toggleMark, toggleTask, typographyRules, undo, undoInputRule, unsetLink, unsetMark, validateSelection, withContent, wordCount };
4054
- //# sourceMappingURL=chunk-5RBMZGKV.js.map
4055
- //# sourceMappingURL=chunk-5RBMZGKV.js.map
4321
+ export { HISTORY_GROUP, HISTORY_PROVIDER, LINE_JOIN, LINE_SPLIT, PASTED_HTML, Transaction, addMarkStep, applyTransaction, blockInputRules, blockRangeSelection, capIndents, caretMarks, carrySelection, cellOf, cellsBetween, commonPrefix, commonSuffix, comparePos, continuesEdit, coreExtensions, countBlock, countDoc, countText, createBlock, createEditor, createPluginKey, createState, defineExtension, deleteBackward, deleteBlocks, deleteForward, deleteRange, deleteSelection, deleteToLineEnd, deleteToLineStart, deleteWordBackward, deleteWordForward, descendantsEnd, detectMac, duplicateBlocks, editEnd, endOf, foreignOrigins, freshBlocks, fromHTML, getPluginState, graphemeCount, graphemePrefix, groupOf, headBlockId, hidingToggle, indent, insertBlockAfter, insertBlocksStep, insertHardBreak, insertMention, insertSlice, insertText, insertTextAt, insertTextWithRules, isActive, isClosedToggle, isCollapsed, isParagraph, isTextFlow, joinBlocksStep, keyName, mapSelection, markCoverage, markExtent, markInputRules, markRanges, moveBlocksDown, moveBlocksStep, moveBlocksTo, moveBlocksUp, movedBlockIds, nextGraphemeOffset, nodeSelection, normalizeKey, orderedRange, outdent, pasteAtCaret, pastedLink, prevGraphemeOffset, primaryRegion, rangeContent, redo, regionInline, regionLength, removeBlocksStep, removeMarkStep, replaceBlockStep, replaceDocStep, replaceInlineStep, runCommands, sameDoc, sameSelection, selectAll, selectedBlockIds, selectedBlockRange, selectionRange, setAttrs, setAttrsStep, setBlockColor, setBlockType, setIndentStep, setLink, setMark, setSelection, setTextAlign, sliceFromClipboard, sliceFromSelection, splitBlockStep, startOf, stepFromJSON, textSelection, toHTML, toMarkdown, toPlainText, toggleMark, toggleTask, typographyRules, undo, undoInputRule, unsetLink, unsetMark, validateSelection, withContent, wordCount };
4322
+ //# sourceMappingURL=chunk-TL2MJOWM.js.map
4323
+ //# sourceMappingURL=chunk-TL2MJOWM.js.map