@harbour-enterprises/superdoc 0.19.0 → 0.20.0-next.10

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/dist/chunks/{PdfViewer-DJb0akn3.cjs → PdfViewer-DOggjrQG.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-D0lSSW0x.es.js → PdfViewer-Dqmc7nRW.es.js} +1 -1
  3. package/dist/chunks/{index-BZOsYVVo.es.js → index-BWLk-GjX.es.js} +4 -3
  4. package/dist/chunks/{index-CeLW_JxI.cjs → index-BbzkKu8K.cjs} +4 -3
  5. package/dist/chunks/{super-editor.es-FNewwzSy.cjs → super-editor.es--aCMUiMA.cjs} +16872 -15653
  6. package/dist/chunks/{super-editor.es-B1rC4GHL.es.js → super-editor.es-Czm6AhQx.es.js} +16872 -15653
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/style.css +44 -6
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-CFVPKGqT.js → converter-CJg7BSkp.js} +13681 -12973
  11. package/dist/super-editor/chunks/{docx-zipper-CGdYHGDa.js → docx-zipper-D56KgEUM.js} +2 -2
  12. package/dist/super-editor/chunks/{editor-DrhZRXX9.js → editor-CZE0QdnY.js} +1802 -1307
  13. package/dist/super-editor/chunks/{toolbar-CKQ-GucL.js → toolbar-YvqMpKof.js} +2 -2
  14. package/dist/super-editor/converter.es.js +1 -1
  15. package/dist/super-editor/docx-zipper.es.js +2 -2
  16. package/dist/super-editor/editor.es.js +3 -3
  17. package/dist/super-editor/file-zipper.es.js +1 -1
  18. package/dist/super-editor/src/core/Editor.d.ts +2 -0
  19. package/dist/super-editor/src/core/helpers/index.d.ts +1 -0
  20. package/dist/super-editor/src/core/helpers/updateDOMAttributes.d.ts +1 -0
  21. package/dist/super-editor/src/core/inputRules/html/transform-copied-lists.d.ts +3 -0
  22. package/dist/super-editor/src/core/super-converter/export-helpers/pre-process-vertical-merge-cells.d.ts +6 -0
  23. package/dist/super-editor/src/core/super-converter/exporter.d.ts +25 -1
  24. package/dist/super-editor/src/core/super-converter/helpers/mediaHelpers.d.ts +2 -0
  25. package/dist/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  26. package/dist/super-editor/src/core/super-converter/v2/exporter/index.d.ts +0 -1
  27. package/dist/super-editor/src/core/super-converter/v2/importer/bookmarkEndImporter.d.ts +6 -0
  28. package/dist/super-editor/src/core/super-converter/v2/importer/bookmarkNodeImporter.d.ts +5 -0
  29. package/dist/super-editor/src/core/super-converter/v2/importer/bookmarkStartImporter.d.ts +6 -0
  30. package/dist/super-editor/src/core/super-converter/v2/importer/imageImporter.d.ts +1 -1
  31. package/dist/super-editor/src/core/super-converter/v2/importer/sdtNodeImporter.d.ts +8 -0
  32. package/dist/super-editor/src/core/super-converter/v2/importer/tableImporter.d.ts +0 -22
  33. package/dist/super-editor/src/core/super-converter/v3/handlers/index.d.ts +4 -0
  34. package/dist/super-editor/src/core/super-converter/v3/handlers/utils.d.ts +10 -3
  35. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bidiVisual/bidiVisual-translator.d.ts +6 -0
  36. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bidiVisual/index.d.ts +1 -0
  37. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-end/attributes/index.d.ts +2 -0
  38. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-end/attributes/w-displaced-by-custom-xml.d.ts +4 -0
  39. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-end/attributes/w-id.d.ts +4 -0
  40. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-end/bookmark-end-translator.d.ts +7 -0
  41. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-end/index.d.ts +1 -0
  42. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/index.d.ts +2 -0
  43. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/w-col-first.d.ts +4 -0
  44. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/w-col-last.d.ts +4 -0
  45. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/w-displaced-by-custom-xml.d.ts +4 -0
  46. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/w-id.d.ts +4 -0
  47. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/attributes/w-name.d.ts +4 -0
  48. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/bookmark-start-translator.d.ts +7 -0
  49. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bookmark-start/index.d.ts +1 -0
  50. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bottom/bottom-translator.d.ts +6 -0
  51. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bottom/index.d.ts +2 -0
  52. package/dist/super-editor/src/core/super-converter/v3/handlers/w/bottom/marginBottom-translator.d.ts +6 -0
  53. package/dist/super-editor/src/core/super-converter/v3/handlers/w/drawing/drawing-translator.d.ts +6 -0
  54. package/dist/super-editor/src/core/super-converter/v3/handlers/w/drawing/index.d.ts +1 -0
  55. package/dist/super-editor/src/core/super-converter/v3/handlers/w/end/end-translator.d.ts +6 -0
  56. package/dist/super-editor/src/core/super-converter/v3/handlers/w/end/index.d.ts +2 -0
  57. package/dist/super-editor/src/core/super-converter/v3/handlers/w/end/marginEnd-translator.d.ts +6 -0
  58. package/dist/super-editor/src/core/super-converter/v3/handlers/w/gridCol/gridCol-translator.d.ts +6 -0
  59. package/dist/super-editor/src/core/super-converter/v3/handlers/w/gridCol/index.d.ts +1 -0
  60. package/dist/super-editor/src/core/super-converter/v3/handlers/w/insideH/index.d.ts +1 -0
  61. package/dist/super-editor/src/core/super-converter/v3/handlers/w/insideH/insideH-translator.d.ts +6 -0
  62. package/dist/super-editor/src/core/super-converter/v3/handlers/w/insideV/index.d.ts +1 -0
  63. package/dist/super-editor/src/core/super-converter/v3/handlers/w/insideV/insideV-translator.d.ts +6 -0
  64. package/dist/super-editor/src/core/super-converter/v3/handlers/w/left/index.d.ts +2 -0
  65. package/dist/super-editor/src/core/super-converter/v3/handlers/w/left/left-translator.d.ts +6 -0
  66. package/dist/super-editor/src/core/super-converter/v3/handlers/w/left/marginLeft-translator.d.ts +6 -0
  67. package/dist/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/w-p-helpers.d.ts +1 -1
  68. package/dist/super-editor/src/core/super-converter/v3/handlers/w/right/index.d.ts +2 -0
  69. package/dist/super-editor/src/core/super-converter/v3/handlers/w/right/marginRight-translator.d.ts +6 -0
  70. package/dist/super-editor/src/core/super-converter/v3/handlers/w/right/right-translator.d.ts +6 -0
  71. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-annotation-node.d.ts +22 -0
  72. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-doc-part-obj.d.ts +6 -0
  73. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-document-section-node.d.ts +6 -0
  74. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/handle-structured-content-node.d.ts +5 -0
  75. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/parse-tag-value-json.d.ts +5 -0
  76. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/sdt-node-type-strategy.d.ts +9 -0
  77. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/translate-document-section.d.ts +7 -0
  78. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/translate-field-annotation.d.ts +80 -0
  79. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/helpers/translate-structured-content.d.ts +5 -0
  80. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/index.d.ts +1 -0
  81. package/dist/super-editor/src/core/super-converter/v3/handlers/w/sdt/sdt-translator.d.ts +6 -0
  82. package/dist/super-editor/src/core/super-converter/v3/handlers/w/shd/index.d.ts +1 -0
  83. package/dist/super-editor/src/core/super-converter/v3/handlers/w/shd/shd-translator.d.ts +6 -0
  84. package/dist/super-editor/src/core/super-converter/v3/handlers/w/start/index.d.ts +2 -0
  85. package/dist/super-editor/src/core/super-converter/v3/handlers/w/start/marginStart-translator.d.ts +6 -0
  86. package/dist/super-editor/src/core/super-converter/v3/handlers/w/start/start-translator.d.ts +6 -0
  87. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tbl/index.d.ts +1 -0
  88. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tbl/tbl-translator.d.ts +28 -0
  89. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblBorders/index.d.ts +1 -0
  90. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblBorders/tblBorders-translator.d.ts +6 -0
  91. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblCaption/index.d.ts +1 -0
  92. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblCaption/tblCaption-translator.d.ts +6 -0
  93. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblCellMar/index.d.ts +1 -0
  94. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblCellMar/tblCellMar-translator.d.ts +2 -0
  95. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblDescription/index.d.ts +1 -0
  96. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblDescription/tblDescription-translator.d.ts +6 -0
  97. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblGrid/index.d.ts +1 -0
  98. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblGrid/tblGrid-helpers.d.ts +5 -0
  99. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblGrid/tblGrid-translator.d.ts +5 -0
  100. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblInd/index.d.ts +1 -0
  101. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblInd/tblInd-translator.d.ts +6 -0
  102. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblLayout/index.d.ts +1 -0
  103. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblLayout/tblLayout-translator.d.ts +6 -0
  104. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblLook/index.d.ts +1 -0
  105. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblLook/tblLook-translator.d.ts +6 -0
  106. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblOverlap/index.d.ts +1 -0
  107. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblOverlap/tblOverlap-translator.d.ts +6 -0
  108. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblPr/index.d.ts +1 -0
  109. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblPr/tblPr-translator.d.ts +5 -0
  110. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyle/index.d.ts +1 -0
  111. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyle/tblStyle-translator.d.ts +6 -0
  112. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyleColBandSize/index.d.ts +1 -0
  113. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyleColBandSize/tblStyleColBandSize-translator.d.ts +6 -0
  114. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyleRowBandSize/index.d.ts +1 -0
  115. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblStyleRowBandSize/tblStyleRowBandSize-translator.d.ts +6 -0
  116. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblW/index.d.ts +1 -0
  117. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblW/tblW-translator.d.ts +6 -0
  118. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblpPr/index.d.ts +1 -0
  119. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tblpPr/tblpPr-translator.d.ts +6 -0
  120. package/dist/super-editor/src/core/super-converter/v3/handlers/w/tc/helpers/legacy-handle-table-cell-node.d.ts +1 -1
  121. package/dist/super-editor/src/core/super-converter/v3/handlers/w/top/index.d.ts +2 -0
  122. package/dist/super-editor/src/core/super-converter/v3/handlers/w/top/marginTop-translator.d.ts +6 -0
  123. package/dist/super-editor/src/core/super-converter/v3/handlers/w/top/top-translator.d.ts +6 -0
  124. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/anchor/anchor-translator.d.ts +6 -0
  125. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/anchor/helpers/handle-anchor-node.d.ts +6 -0
  126. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/anchor/helpers/translate-anchor-node.d.ts +6 -0
  127. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/anchor/index.d.ts +1 -0
  128. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/helpers/decode-image-node-helpers.d.ts +18 -0
  129. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/helpers/encode-image-node-helpers.d.ts +6 -0
  130. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/inline/helpers/handle-inline-node.d.ts +6 -0
  131. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/inline/helpers/translate-inline-node.d.ts +6 -0
  132. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/inline/index.d.ts +1 -0
  133. package/dist/super-editor/src/core/super-converter/v3/handlers/wp/inline/inline-translator.d.ts +6 -0
  134. package/dist/super-editor/src/core/super-converter/v3/node-translator/node-translator.d.ts +19 -9
  135. package/dist/super-editor/src/extensions/block-node/block-node.d.ts +30 -5
  136. package/dist/super-editor/src/extensions/bold/bold.d.ts +20 -0
  137. package/dist/super-editor/src/extensions/bookmarks/bookmark-end.d.ts +6 -0
  138. package/dist/super-editor/src/extensions/bookmarks/index.d.ts +2 -1
  139. package/dist/super-editor/src/extensions/bullet-list/bullet-list.d.ts +12 -0
  140. package/dist/super-editor/src/extensions/color/color.d.ts +26 -0
  141. package/dist/super-editor/src/extensions/content-block/content-block.d.ts +30 -0
  142. package/dist/super-editor/src/extensions/custom-selection/custom-selection.d.ts +16 -0
  143. package/dist/super-editor/src/extensions/document/document.d.ts +26 -0
  144. package/dist/super-editor/src/extensions/dropcursor/dropcursor.d.ts +26 -0
  145. package/dist/super-editor/src/extensions/font-family/font-family.d.ts +29 -0
  146. package/dist/super-editor/src/extensions/font-size/font-size.d.ts +21 -0
  147. package/dist/super-editor/src/extensions/format-commands/format-commands.d.ts +9 -0
  148. package/dist/super-editor/src/extensions/gapcursor/gapcursor.d.ts +9 -0
  149. package/dist/super-editor/src/extensions/heading/heading.d.ts +12 -6
  150. package/dist/super-editor/src/extensions/highlight/highlight.d.ts +20 -0
  151. package/dist/super-editor/src/extensions/history/history.d.ts +7 -15
  152. package/dist/super-editor/src/extensions/image/image.d.ts +78 -0
  153. package/dist/super-editor/src/extensions/image/imageHelpers/fileNameUtils.d.ts +3 -0
  154. package/dist/super-editor/src/extensions/image/imageHelpers/handleBase64.d.ts +1 -0
  155. package/dist/super-editor/src/extensions/image/imageHelpers/handleUrl.d.ts +2 -0
  156. package/dist/super-editor/src/extensions/image/imageHelpers/imageRegistrationPlugin.d.ts +11 -0
  157. package/dist/super-editor/src/extensions/image/imageHelpers/index.d.ts +3 -1
  158. package/dist/super-editor/src/extensions/image/imageHelpers/processUploadedImage.d.ts +2 -2
  159. package/dist/super-editor/src/extensions/image/imageHelpers/rotation.d.ts +4 -0
  160. package/dist/super-editor/src/extensions/image/imageHelpers/startImageUpload.d.ts +18 -23
  161. package/dist/super-editor/src/extensions/index.d.ts +2 -1
  162. package/dist/super-editor/src/extensions/italic/italic.d.ts +10 -0
  163. package/dist/super-editor/src/extensions/line-break/line-break.d.ts +43 -0
  164. package/dist/super-editor/src/extensions/line-height/line-height.d.ts +22 -0
  165. package/dist/super-editor/src/extensions/link/link.d.ts +53 -25
  166. package/dist/super-editor/src/extensions/linked-styles/linked-styles.d.ts +9 -0
  167. package/dist/super-editor/src/extensions/list-item/list-item.d.ts +48 -0
  168. package/dist/super-editor/src/extensions/mention/mention.d.ts +26 -0
  169. package/dist/super-editor/src/extensions/noderesizer/noderesizer.d.ts +14 -0
  170. package/dist/super-editor/src/extensions/ordered-list/ordered-list.d.ts +35 -0
  171. package/dist/super-editor/src/extensions/page-number/page-number.d.ts +52 -0
  172. package/dist/super-editor/src/extensions/paragraph/paragraph.d.ts +49 -0
  173. package/dist/super-editor/src/extensions/placeholder/placeholder.d.ts +15 -0
  174. package/dist/super-editor/src/extensions/popover-plugin/popover-plugin.d.ts +9 -0
  175. package/dist/super-editor/src/extensions/run-item/run-item.d.ts +24 -0
  176. package/dist/super-editor/src/extensions/search/search.d.ts +11 -2
  177. package/dist/super-editor/src/extensions/shape-container/shape-container.d.ts +29 -0
  178. package/dist/super-editor/src/extensions/shape-textbox/shape-textbox.d.ts +26 -0
  179. package/dist/super-editor/src/extensions/slash-menu/slash-menu.d.ts +9 -0
  180. package/dist/super-editor/src/extensions/strike/strike.d.ts +10 -0
  181. package/dist/super-editor/src/extensions/structured-content/StructuredContentBlockView.d.ts +9 -0
  182. package/dist/super-editor/src/extensions/structured-content/StructuredContentInlineView.d.ts +9 -0
  183. package/dist/super-editor/src/extensions/structured-content/StructuredContentViewBase.d.ts +24 -0
  184. package/dist/super-editor/src/extensions/structured-content/document-section.d.ts +46 -27
  185. package/dist/super-editor/src/extensions/structured-content/structured-content-block.d.ts +29 -1
  186. package/dist/super-editor/src/extensions/structured-content/structured-content.d.ts +29 -1
  187. package/dist/super-editor/src/extensions/tab/tab.d.ts +25 -0
  188. package/dist/super-editor/src/extensions/table/table.d.ts +376 -55
  189. package/dist/super-editor/src/extensions/table-cell/table-cell.d.ts +41 -0
  190. package/dist/super-editor/src/extensions/table-header/table-header.d.ts +22 -0
  191. package/dist/super-editor/src/extensions/table-row/table-row.d.ts +28 -0
  192. package/dist/super-editor/src/extensions/text/text.d.ts +14 -0
  193. package/dist/super-editor/src/extensions/text-align/text-align.d.ts +22 -0
  194. package/dist/super-editor/src/extensions/text-indent/text-indent.d.ts +19 -10
  195. package/dist/super-editor/src/extensions/text-style/text-style.d.ts +20 -0
  196. package/dist/super-editor/src/extensions/text-transform/text-transform.d.ts +20 -0
  197. package/dist/super-editor/src/extensions/underline/underline.d.ts +25 -0
  198. package/dist/super-editor/src/tests/helpers/editor-test-utils.d.ts +14 -0
  199. package/dist/super-editor/style.css +44 -6
  200. package/dist/super-editor/super-editor.es.js +72 -57
  201. package/dist/super-editor/toolbar.es.js +2 -2
  202. package/dist/super-editor.cjs +1 -1
  203. package/dist/super-editor.es.js +1 -1
  204. package/dist/superdoc.cjs +2 -2
  205. package/dist/superdoc.es.js +2 -2
  206. package/dist/superdoc.umd.js +17566 -16346
  207. package/dist/superdoc.umd.js.map +1 -1
  208. package/package.json +1 -1
  209. package/dist/super-editor/src/core/super-converter/v2/exporter/documentSectionExporter.d.ts +0 -1
  210. package/dist/super-editor/src/core/super-converter/v2/importer/annotationImporter.d.ts +0 -9
  211. package/dist/super-editor/src/core/super-converter/v2/importer/docPartGalleryImporter.d.ts +0 -1
  212. package/dist/super-editor/src/core/super-converter/v2/importer/docPartObjImporter.d.ts +0 -4
  213. package/dist/super-editor/src/core/super-converter/v2/importer/structuredDocumentNodeImporter.d.ts +0 -8
  214. package/dist/super-editor/src/extensions/image/imageHelpers/imagePlaceholderPlugin.d.ts +0 -5
  215. /package/dist/super-editor/src/extensions/bookmarks/{bookmarks.d.ts → bookmark-start.d.ts} +0 -0
@@ -2,19 +2,19 @@ var __defProp = Object.defineProperty;
2
2
  var __typeError = (msg) => {
3
3
  throw TypeError(msg);
4
4
  };
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
6
+ var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
7
7
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
8
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
9
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
10
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
11
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
- var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _ListItemNodeView_instances, init_fn2, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _DocumentSectionView_instances, init_fn3, addToolTip_fn;
12
+ var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, registerPluginByNameIfNotExists_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, initPagination_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _ListItemNodeView_instances, init_fn2, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _DocumentSectionView_instances, init_fn3, addToolTip_fn;
13
13
  import * as Y from "yjs";
14
14
  import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
15
- import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as InputRule, ah as kebabCase, ai as findParentNodeClosestToPos, aj as getListItemStyleDefinitions, ak as docxNumberigHelpers, al as parseIndentElement, am as combineIndents, an as StepMap, ao as getColStyleDeclaration, ap as SelectionRange, aq as Transform, ar as isInTable$1, as as createColGroup, at as generateDocxRandomId, au as insertNewRelationship, av as htmlHandler } from "./converter-CFVPKGqT.js";
15
+ import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as ReplaceStep, E as NodeRange, G as findWrapping, L as ListHelpers, H as findParentNode, I as isMacOS, J as isIOS, K as getSchemaTypeByName, O as inputRulesPlugin, Q as TrackDeleteMarkName, U as TrackInsertMarkName, V as v4, W as TrackFormatMarkName, X as comments_module_events, Y as findMark, Z as objectIncludes, _ as AddMarkStep, $ as RemoveMarkStep, a0 as twipsToLines, a1 as pixelsToTwips, a2 as helpers, a3 as posToDOMRect, a4 as CommandService, a5 as SuperConverter, a6 as createDocument, a7 as createDocFromMarkdown, a8 as createDocFromHTML, a9 as EditorState, aa as hasSomeParentWithClass, ab as isActive, ac as unflattenListsInHtml, ad as parseSizeUnit, ae as minMax, af as getLineHeightValueString, ag as InputRule, ah as kebabCase, ai as findParentNodeClosestToPos, aj as getListItemStyleDefinitions, ak as docxNumberigHelpers, al as parseIndentElement, am as combineIndents, an as StepMap, ao as SelectionRange, ap as Transform, aq as isInTable$1, ar as generateDocxRandomId, as as insertNewRelationship, at as updateDOMAttributes, au as htmlHandler } from "./converter-CJg7BSkp.js";
16
16
  import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
17
- import { D as DocxZipper } from "./docx-zipper-CGdYHGDa.js";
17
+ import { D as DocxZipper } from "./docx-zipper-D56KgEUM.js";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
20
20
  };
@@ -662,11 +662,11 @@ function hasBlockDesc(dom) {
662
662
  const selectionCollapsed = function(domSel) {
663
663
  return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset);
664
664
  };
665
- function keyEvent(keyCode, key) {
665
+ function keyEvent(keyCode, key2) {
666
666
  let event = document.createEvent("Event");
667
667
  event.initEvent("keydown", true, true);
668
668
  event.keyCode = keyCode;
669
- event.key = event.code = key;
669
+ event.key = event.code = key2;
670
670
  return event;
671
671
  }
672
672
  function deepActiveElement(doc2) {
@@ -1872,17 +1872,18 @@ class NodeViewDesc extends ViewDesc {
1872
1872
  }
1873
1873
  // Mark this node as being the selected node.
1874
1874
  selectNode() {
1875
- if (this.nodeDOM.nodeType == 1)
1875
+ if (this.nodeDOM.nodeType == 1) {
1876
1876
  this.nodeDOM.classList.add("ProseMirror-selectednode");
1877
- if (this.contentDOM || !this.node.type.spec.draggable)
1878
- this.dom.draggable = true;
1877
+ if (this.contentDOM || !this.node.type.spec.draggable)
1878
+ this.nodeDOM.draggable = true;
1879
+ }
1879
1880
  }
1880
1881
  // Remove selected node marking from this node.
1881
1882
  deselectNode() {
1882
1883
  if (this.nodeDOM.nodeType == 1) {
1883
1884
  this.nodeDOM.classList.remove("ProseMirror-selectednode");
1884
1885
  if (this.contentDOM || !this.node.type.spec.draggable)
1885
- this.dom.removeAttribute("draggable");
1886
+ this.nodeDOM.removeAttribute("draggable");
1886
1887
  }
1887
1888
  }
1888
1889
  get domAtom() {
@@ -3542,7 +3543,7 @@ class MouseDown {
3542
3543
  }
3543
3544
  const target = flushed ? null : event.target;
3544
3545
  const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
3545
- this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
3546
+ this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
3546
3547
  let { selection } = view.state;
3547
3548
  if (event.button == 0 && targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)
3548
3549
  this.mightDrag = {
@@ -5913,9 +5914,9 @@ const writeAny = (encoder, data) => {
5913
5914
  const keys2 = Object.keys(data);
5914
5915
  writeVarUint(encoder, keys2.length);
5915
5916
  for (let i = 0; i < keys2.length; i++) {
5916
- const key = keys2[i];
5917
- writeVarString(encoder, key);
5918
- writeAny(encoder, data[key]);
5917
+ const key2 = keys2[i];
5918
+ writeVarString(encoder, key2);
5919
+ writeAny(encoder, data[key2]);
5919
5920
  }
5920
5921
  }
5921
5922
  break;
@@ -5934,17 +5935,17 @@ const unexpectedCase = () => {
5934
5935
  throw create$1("Unexpected case");
5935
5936
  };
5936
5937
  const create = () => /* @__PURE__ */ new Map();
5937
- const setIfUndefined = (map2, key, createT) => {
5938
- let set = map2.get(key);
5938
+ const setIfUndefined = (map2, key2, createT) => {
5939
+ let set = map2.get(key2);
5939
5940
  if (set === void 0) {
5940
- map2.set(key, set = createT());
5941
+ map2.set(key2, set = createT());
5941
5942
  }
5942
5943
  return set;
5943
5944
  };
5944
5945
  const keys = Object.keys;
5945
5946
  const every = (obj, f) => {
5946
- for (const key in obj) {
5947
- if (!f(obj[key], key)) {
5947
+ for (const key2 in obj) {
5948
+ if (!f(obj[key2], key2)) {
5948
5949
  return false;
5949
5950
  }
5950
5951
  }
@@ -6000,14 +6001,14 @@ class VarStoragePolyfill {
6000
6001
  * @param {string} key
6001
6002
  * @param {any} newValue
6002
6003
  */
6003
- setItem(key, newValue) {
6004
- this.map.set(key, newValue);
6004
+ setItem(key2, newValue) {
6005
+ this.map.set(key2, newValue);
6005
6006
  }
6006
6007
  /**
6007
6008
  * @param {string} key
6008
6009
  */
6009
- getItem(key) {
6010
- return this.map.get(key);
6010
+ getItem(key2) {
6011
+ return this.map.get(key2);
6011
6012
  }
6012
6013
  }
6013
6014
  let _localStorage = new VarStoragePolyfill();
@@ -6050,9 +6051,9 @@ const computeParams = () => {
6050
6051
  params = create();
6051
6052
  (location.search || "?").slice(1).split("&").forEach((kv) => {
6052
6053
  if (kv.length !== 0) {
6053
- const [key, value] = kv.split("=");
6054
- params.set(`--${fromCamelCase(key, "-")}`, value);
6055
- params.set(`-${fromCamelCase(key, "-")}`, value);
6054
+ const [key2, value] = kv.split("=");
6055
+ params.set(`--${fromCamelCase(key2, "-")}`, value);
6056
+ params.set(`-${fromCamelCase(key2, "-")}`, value);
6056
6057
  }
6057
6058
  });
6058
6059
  } else {
@@ -6335,8 +6336,8 @@ const ySyncPlugin = (yXmlFragment, {
6335
6336
  const change = tr.getMeta(ySyncPluginKey);
6336
6337
  if (change !== void 0) {
6337
6338
  pluginState = Object.assign({}, pluginState);
6338
- for (const key in change) {
6339
- pluginState[key] = change[key];
6339
+ for (const key2 in change) {
6340
+ pluginState[key2] = change[key2];
6340
6341
  }
6341
6342
  }
6342
6343
  pluginState.addToHistory = tr.getMeta("addToHistory") !== false;
@@ -6608,7 +6609,7 @@ class ProsemirrorBinding {
6608
6609
  snapshot = Y.snapshot(historyDoc);
6609
6610
  if (historyType._item === null) {
6610
6611
  const rootKey = Array.from(this.doc.share.keys()).find(
6611
- (key) => this.doc.share.get(key) === this.type
6612
+ (key2) => this.doc.share.get(key2) === this.type
6612
6613
  );
6613
6614
  historyType = historyDoc.getXmlFragment(rootKey);
6614
6615
  } else {
@@ -6897,10 +6898,10 @@ const createTypeFromTextNodes = (nodes, meta) => {
6897
6898
  };
6898
6899
  const createTypeFromElementNode = (node, meta) => {
6899
6900
  const type = new Y.XmlElement(node.type.name);
6900
- for (const key in node.attrs) {
6901
- const val = node.attrs[key];
6902
- if (val !== null && key !== "ychange") {
6903
- type.setAttribute(key, val);
6901
+ for (const key2 in node.attrs) {
6902
+ const val = node.attrs[key2];
6903
+ if (val !== null && key2 !== "ychange") {
6904
+ type.setAttribute(key2, val);
6904
6905
  }
6905
6906
  }
6906
6907
  type.insert(
@@ -6915,13 +6916,13 @@ const createTypeFromElementNode = (node, meta) => {
6915
6916
  const createTypeFromTextOrElementNode = (node, meta) => node instanceof Array ? createTypeFromTextNodes(node, meta) : createTypeFromElementNode(node, meta);
6916
6917
  const isObject = (val) => typeof val === "object" && val !== null;
6917
6918
  const equalAttrs = (pattrs, yattrs) => {
6918
- const keys2 = Object.keys(pattrs).filter((key) => pattrs[key] !== null);
6919
- let eq = keys2.length === (yattrs == null ? 0 : Object.keys(yattrs).filter((key) => yattrs[key] !== null).length);
6919
+ const keys2 = Object.keys(pattrs).filter((key2) => pattrs[key2] !== null);
6920
+ let eq = keys2.length === (yattrs == null ? 0 : Object.keys(yattrs).filter((key2) => yattrs[key2] !== null).length);
6920
6921
  for (let i = 0; i < keys2.length && eq; i++) {
6921
- const key = keys2[i];
6922
- const l = pattrs[key];
6923
- const r2 = yattrs[key];
6924
- eq = key === "ychange" || l === r2 || isObject(l) && isObject(r2) && equalAttrs(l, r2);
6922
+ const key2 = keys2[i];
6923
+ const l = pattrs[key2];
6924
+ const r2 = yattrs[key2];
6925
+ eq = key2 === "ychange" || l === r2 || isObject(l) && isObject(r2) && equalAttrs(l, r2);
6925
6926
  }
6926
6927
  return eq;
6927
6928
  };
@@ -7068,18 +7069,18 @@ const updateYFragment = (y, yDomFragment, pNode, meta) => {
7068
7069
  if (yDomFragment instanceof Y.XmlElement) {
7069
7070
  const yDomAttrs = yDomFragment.getAttributes();
7070
7071
  const pAttrs = pNode.attrs;
7071
- for (const key in pAttrs) {
7072
- if (pAttrs[key] !== null) {
7073
- if (yDomAttrs[key] !== pAttrs[key] && key !== "ychange") {
7074
- yDomFragment.setAttribute(key, pAttrs[key]);
7072
+ for (const key2 in pAttrs) {
7073
+ if (pAttrs[key2] !== null) {
7074
+ if (yDomAttrs[key2] !== pAttrs[key2] && key2 !== "ychange") {
7075
+ yDomFragment.setAttribute(key2, pAttrs[key2]);
7075
7076
  }
7076
7077
  } else {
7077
- yDomFragment.removeAttribute(key);
7078
+ yDomFragment.removeAttribute(key2);
7078
7079
  }
7079
7080
  }
7080
- for (const key in yDomAttrs) {
7081
- if (pAttrs[key] === void 0) {
7082
- yDomFragment.removeAttribute(key);
7081
+ for (const key2 in yDomAttrs) {
7082
+ if (pAttrs[key2] === void 0) {
7083
+ yDomFragment.removeAttribute(key2);
7083
7084
  }
7084
7085
  }
7085
7086
  }
@@ -7210,19 +7211,19 @@ const updateMetas = () => {
7210
7211
  const tr = view.state.tr;
7211
7212
  const syncState = ySyncPluginKey.getState(view.state);
7212
7213
  if (syncState && syncState.binding && !syncState.binding.isDestroyed) {
7213
- metas.forEach((val, key) => {
7214
- tr.setMeta(key, val);
7214
+ metas.forEach((val, key2) => {
7215
+ tr.setMeta(key2, val);
7215
7216
  });
7216
7217
  view.dispatch(tr);
7217
7218
  }
7218
7219
  });
7219
7220
  };
7220
- const setMeta$1 = (view, key, value) => {
7221
+ const setMeta$1 = (view, key2, value) => {
7221
7222
  if (!viewsToUpdate) {
7222
7223
  viewsToUpdate = /* @__PURE__ */ new Map();
7223
7224
  timeout(0, updateMetas);
7224
7225
  }
7225
- setIfUndefined(viewsToUpdate, view, create).set(key, value);
7226
+ setIfUndefined(viewsToUpdate, view, create).set(key2, value);
7226
7227
  };
7227
7228
  const absolutePositionToRelativePosition = (pos, type, mapping) => {
7228
7229
  if (pos === 0) {
@@ -7682,12 +7683,6 @@ const History = Extension.create({
7682
7683
  name: "history",
7683
7684
  addOptions() {
7684
7685
  return {
7685
- /**
7686
- * @typedef {Object} HistoryOptions
7687
- * @category Options
7688
- * @property {number} [depth=100] - Maximum undo/redo steps to remember
7689
- * @property {number} [newGroupDelay=500] - Milliseconds to wait before starting a new history group
7690
- */
7691
7686
  depth: 100,
7692
7687
  newGroupDelay: 500
7693
7688
  };
@@ -7706,9 +7701,8 @@ const History = Extension.create({
7706
7701
  /**
7707
7702
  * Undo the last action
7708
7703
  * @category Command
7709
- * @returns {Function} Command function
7710
7704
  * @example
7711
- * undo()
7705
+ * editor.commands.undo()
7712
7706
  * @note Groups changes within the newGroupDelay window
7713
7707
  */
7714
7708
  undo: () => ({ state, dispatch, tr }) => {
@@ -7722,9 +7716,8 @@ const History = Extension.create({
7722
7716
  /**
7723
7717
  * Redo the last undone action
7724
7718
  * @category Command
7725
- * @returns {Function} Command function
7726
7719
  * @example
7727
- * redo()
7720
+ * editor.commands.redo()
7728
7721
  * @note Only available after an undo action
7729
7722
  */
7730
7723
  redo: () => ({ state, dispatch, tr }) => {
@@ -7922,21 +7915,21 @@ class Attribute {
7922
7915
  let attrs = {};
7923
7916
  for (const item of items) {
7924
7917
  const mergedAttributes = { ...attrs };
7925
- for (const [key, value] of Object.entries(item)) {
7926
- const exists = mergedAttributes[key];
7918
+ for (const [key2, value] of Object.entries(item)) {
7919
+ const exists = mergedAttributes[key2];
7927
7920
  if (!exists) {
7928
- mergedAttributes[key] = value;
7921
+ mergedAttributes[key2] = value;
7929
7922
  continue;
7930
7923
  }
7931
- if (key === "class") {
7924
+ if (key2 === "class") {
7932
7925
  const valueClasses = value ? value.split(" ") : [];
7933
- const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : [];
7926
+ const existingClasses = mergedAttributes[key2] ? mergedAttributes[key2].split(" ") : [];
7934
7927
  const insertClasses = valueClasses.filter((value2) => !existingClasses.includes(value2));
7935
- mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
7936
- } else if (key === "style") {
7937
- mergedAttributes[key] = [mergedAttributes[key], value].join("; ");
7928
+ mergedAttributes[key2] = [...existingClasses, ...insertClasses].join(" ");
7929
+ } else if (key2 === "style") {
7930
+ mergedAttributes[key2] = [mergedAttributes[key2], value].join("; ");
7938
7931
  } else {
7939
- mergedAttributes[key] = value;
7932
+ mergedAttributes[key2] = value;
7940
7933
  }
7941
7934
  }
7942
7935
  attrs = mergedAttributes;
@@ -8246,8 +8239,8 @@ const insertTabNode = () => ({ tr, state, dispatch }) => {
8246
8239
  if (dispatch) dispatch(tr);
8247
8240
  return true;
8248
8241
  };
8249
- const setMeta = (key, value) => ({ tr }) => {
8250
- tr.setMeta(key, value);
8242
+ const setMeta = (key2, value) => ({ tr }) => {
8243
+ tr.setMeta(key2, value);
8251
8244
  return true;
8252
8245
  };
8253
8246
  const ensureMarks = (state, splittableMarks) => {
@@ -11375,14 +11368,14 @@ const updateYdocDocxData = async (editor, ydoc) => {
11375
11368
  const metaMap = ydoc.getMap("meta");
11376
11369
  const docx = [...metaMap.get("docx")];
11377
11370
  const newXml = await editor.exportDocx({ getUpdatedDocs: true });
11378
- Object.keys(newXml).forEach((key) => {
11379
- const fileIndex = docx.findIndex((item) => item.name === key);
11371
+ Object.keys(newXml).forEach((key2) => {
11372
+ const fileIndex = docx.findIndex((item) => item.name === key2);
11380
11373
  if (fileIndex > -1) {
11381
11374
  docx.splice(fileIndex, 1);
11382
11375
  }
11383
11376
  docx.push({
11384
- name: key,
11385
- content: newXml[key]
11377
+ name: key2,
11378
+ content: newXml[key2]
11386
11379
  });
11387
11380
  });
11388
11381
  ydoc.transact(
@@ -11398,8 +11391,8 @@ const initPaginationData = async (editor) => {
11398
11391
  const sectionData = { headers: {}, footers: {} };
11399
11392
  const headerIds = editor.converter.headerIds.ids;
11400
11393
  const footerIds = editor.converter.footerIds.ids;
11401
- for (let key in headerIds) {
11402
- const sectionId = headerIds[key];
11394
+ for (let key2 in headerIds) {
11395
+ const sectionId = headerIds[key2];
11403
11396
  if (!sectionId) continue;
11404
11397
  const dataForThisSection = editor.converter.headers[sectionId];
11405
11398
  if (!sectionData.headers[sectionId]) sectionData.headers[sectionId] = {};
@@ -11409,8 +11402,8 @@ const initPaginationData = async (editor) => {
11409
11402
  sectionData.headers[sectionId].sectionEditor = sectionEditor;
11410
11403
  sectionData.headers[sectionId].sectionContainer = sectionContainer;
11411
11404
  }
11412
- for (let key in footerIds) {
11413
- const sectionId = footerIds[key];
11405
+ for (let key2 in footerIds) {
11406
+ const sectionId = footerIds[key2];
11414
11407
  if (!sectionId) continue;
11415
11408
  const dataForThisSection = editor.converter.footers[sectionId];
11416
11409
  if (!sectionData.headers[sectionId]) sectionData.footers[sectionId] = {};
@@ -12479,16 +12472,16 @@ const generateTableIfNecessary = ({ tableNode, annotationValues, tr, state }) =>
12479
12472
  if (rowsToGenerate <= 1) return;
12480
12473
  const validateAttributes = (attrs) => {
12481
12474
  const cleaned = {};
12482
- for (const [key, value] of Object.entries(attrs)) {
12475
+ for (const [key2, value] of Object.entries(attrs)) {
12483
12476
  if (value !== void 0 && value !== null) {
12484
- if (key === "displayLabel") {
12485
- cleaned[key] = String(value);
12486
- } else if (key === "rawHtml" || key === "linkUrl" || key === "imageSrc") {
12487
- cleaned[key] = String(value);
12477
+ if (key2 === "displayLabel") {
12478
+ cleaned[key2] = String(value);
12479
+ } else if (key2 === "rawHtml" || key2 === "linkUrl" || key2 === "imageSrc") {
12480
+ cleaned[key2] = String(value);
12488
12481
  } else if (typeof value === "string" && value.length > 0) {
12489
- cleaned[key] = value;
12482
+ cleaned[key2] = value;
12490
12483
  } else if (typeof value !== "string") {
12491
- cleaned[key] = value;
12484
+ cleaned[key2] = value;
12492
12485
  }
12493
12486
  }
12494
12487
  }
@@ -12766,10 +12759,10 @@ const Collaboration = Extension.create({
12766
12759
  this.options.fragment = fragment;
12767
12760
  const metaMap = this.options.ydoc.getMap("media");
12768
12761
  metaMap.observe((event) => {
12769
- event.changes.keys.forEach((_, key) => {
12770
- if (!(key in this.editor.storage.image.media)) {
12771
- const fileData = metaMap.get(key);
12772
- this.editor.storage.image.media[key] = fileData;
12762
+ event.changes.keys.forEach((_, key2) => {
12763
+ if (!(key2 in this.editor.storage.image.media)) {
12764
+ const fileData = metaMap.get(key2);
12765
+ this.editor.storage.image.media[key2] = fileData;
12773
12766
  }
12774
12767
  });
12775
12768
  });
@@ -12789,8 +12782,8 @@ const initializeMetaMap = (ydoc, editor) => {
12789
12782
  metaMap.set("docx", editor.options.content);
12790
12783
  metaMap.set("fonts", editor.options.fonts);
12791
12784
  const mediaMap = ydoc.getMap("media");
12792
- Object.entries(editor.options.mediaFiles).forEach(([key, value]) => {
12793
- mediaMap.set(key, value);
12785
+ Object.entries(editor.options.mediaFiles).forEach(([key2, value]) => {
12786
+ mediaMap.set(key2, value);
12794
12787
  });
12795
12788
  };
12796
12789
  const checkDocxChanged = (transaction) => {
@@ -13552,8 +13545,8 @@ function processRelationships(root, convertedXml, results) {
13552
13545
  };
13553
13546
  const seenIds = /* @__PURE__ */ new Set();
13554
13547
  const filtered = [];
13555
- function extractStringAttr(attrs, key) {
13556
- return typeof attrs[key] === "string" ? attrs[key].trim() : "";
13548
+ function extractStringAttr(attrs, key2) {
13549
+ return typeof attrs[key2] === "string" ? attrs[key2].trim() : "";
13557
13550
  }
13558
13551
  for (const rel of root.elements) {
13559
13552
  rel.attributes = rel.attributes || {};
@@ -13775,10 +13768,10 @@ class SuperValidator {
13775
13768
  this.logger.debug("Document analysis:", documentAnalysis);
13776
13769
  let hasModifiedDocument = false;
13777
13770
  const validationResults = [];
13778
- Object.entries(__privateGet(this, _stateValidators)).forEach(([key, validator]) => {
13779
- this.logger.debug(`🕵 Validating with ${key}...`);
13771
+ Object.entries(__privateGet(this, _stateValidators)).forEach(([key2, validator]) => {
13772
+ this.logger.debug(`🕵 Validating with ${key2}...`);
13780
13773
  const { results, modified } = validator(tr, documentAnalysis);
13781
- validationResults.push({ key, results });
13774
+ validationResults.push({ key: key2, results });
13782
13775
  hasModifiedDocument = hasModifiedDocument || modified;
13783
13776
  });
13784
13777
  if (!this.dryRun) dispatch(tr);
@@ -13795,10 +13788,10 @@ class SuperValidator {
13795
13788
  const { dispatch } = __privateGet(this, _editor).view;
13796
13789
  let hasModifiedDocument = false;
13797
13790
  const validationResults = [];
13798
- Object.entries(__privateGet(this, _xmlValidators)).forEach(([key, validator]) => {
13799
- this.logger.debug(`🕵 Validating export with ${key}...`);
13791
+ Object.entries(__privateGet(this, _xmlValidators)).forEach(([key2, validator]) => {
13792
+ this.logger.debug(`🕵 Validating export with ${key2}...`);
13800
13793
  const { results, modified } = validator();
13801
- validationResults.push({ key, results });
13794
+ validationResults.push({ key: key2, results });
13802
13795
  hasModifiedDocument = hasModifiedDocument || modified;
13803
13796
  });
13804
13797
  if (!this.dryRun && hasModifiedDocument) dispatch(tr);
@@ -13822,11 +13815,11 @@ initializeValidators_fn = function() {
13822
13815
  const requiredMarks = /* @__PURE__ */ new Set();
13823
13816
  const initializeValidatorSet = (validatorFactories) => {
13824
13817
  return Object.fromEntries(
13825
- Object.entries(validatorFactories).map(([key, factory]) => {
13826
- const validatorLogger = this.logger.withPrefix(key);
13818
+ Object.entries(validatorFactories).map(([key2, factory]) => {
13819
+ const validatorLogger = this.logger.withPrefix(key2);
13827
13820
  const validator = factory({ editor: __privateGet(this, _editor), logger: validatorLogger });
13828
13821
  __privateMethod(this, _SuperValidator_instances, collectValidatorRequirements_fn).call(this, validator, requiredNodes, requiredMarks);
13829
- return [key, validator];
13822
+ return [key2, validator];
13830
13823
  })
13831
13824
  );
13832
13825
  };
@@ -13893,6 +13886,77 @@ analyzeDocument_fn = function() {
13893
13886
  doc2.descendants(collectElements);
13894
13887
  return analysis;
13895
13888
  };
13889
+ const transformListsInCopiedContent = (html) => {
13890
+ const container = document.createElement("div");
13891
+ container.innerHTML = html;
13892
+ const result = [];
13893
+ const stack = [];
13894
+ const flushStackUntil = (level) => {
13895
+ while (stack.length && stack[stack.length - 1].level >= level) {
13896
+ const top2 = stack.pop();
13897
+ if (stack.length) {
13898
+ stack[stack.length - 1].el.appendChild(top2.el);
13899
+ } else {
13900
+ result.push(top2.el.outerHTML);
13901
+ }
13902
+ }
13903
+ };
13904
+ Array.from(container.childNodes).forEach((node) => {
13905
+ if (node.nodeType !== Node.ELEMENT_NODE) {
13906
+ result.push(node.outerHTML || node.textContent);
13907
+ return;
13908
+ }
13909
+ if (node.tagName.toLowerCase() === "ol" || node.tagName.toLowerCase() === "ul") {
13910
+ const child = getFirstElementChild(node);
13911
+ const level = getLevel(child);
13912
+ const numFmt = child.getAttribute("data-num-fmt");
13913
+ const lvlText = child.getAttribute("data-lvl-text");
13914
+ const tag = node.tagName.toLowerCase();
13915
+ const li = child.cloneNode(true);
13916
+ li.setAttribute("aria-level", level + 1);
13917
+ li.style["list-style-type"] = getListStyleType(numFmt, lvlText);
13918
+ if (!stack.length || stack[stack.length - 1].level < level) {
13919
+ const newList = document.createElement(tag);
13920
+ stack.push({ tag, level, el: newList });
13921
+ } else if (stack[stack.length - 1].level > level) {
13922
+ flushStackUntil(level + 1);
13923
+ } else if (stack[stack.length - 1].tag !== tag) {
13924
+ flushStackUntil(level);
13925
+ const newList = document.createElement(tag);
13926
+ stack.push({ tag, level, el: newList });
13927
+ }
13928
+ stack[stack.length - 1].el.appendChild(li);
13929
+ } else {
13930
+ flushStackUntil(0);
13931
+ result.push(node.outerHTML);
13932
+ }
13933
+ });
13934
+ flushStackUntil(0);
13935
+ return result.join("");
13936
+ };
13937
+ const getListStyleType = (numFmt, lvlText) => {
13938
+ const bulletFmtMap = /* @__PURE__ */ new Map([
13939
+ ["●", "disc"],
13940
+ ["◦", "circle"],
13941
+ ["▪", "square"]
13942
+ ]);
13943
+ if (numFmt === "bullet") return bulletFmtMap.get(lvlText) || "disc";
13944
+ const fmtMap = /* @__PURE__ */ new Map([
13945
+ ["decimal", "decimal"],
13946
+ ["lowerLetter", "lower-alpha"],
13947
+ ["upperLetter", "upper-alpha"],
13948
+ ["lowerRoman", "lower-roman"],
13949
+ ["upperRoman", "upper-roman"]
13950
+ ]);
13951
+ return lvlText.startsWith("0") ? "decimal-leading-zero" : fmtMap.get(numFmt);
13952
+ };
13953
+ function getFirstElementChild(node) {
13954
+ return Array.from(node.childNodes).find((n) => n.nodeType === Node.ELEMENT_NODE) || null;
13955
+ }
13956
+ const getLevel = (node) => {
13957
+ const lvl = node.getAttribute("data-level");
13958
+ return lvl ? parseInt(lvl, 10) : 0;
13959
+ };
13896
13960
  const _Editor = class _Editor extends EventEmitter {
13897
13961
  /**
13898
13962
  * Create a new Editor instance
@@ -14471,6 +14535,8 @@ const _Editor = class _Editor extends EventEmitter {
14471
14535
  }
14472
14536
  /**
14473
14537
  * Get the editor content as HTML
14538
+ * @param {Object} options - Options for the HTML serializer
14539
+ * @param {boolean} [options.unflattenLists] - Whether to unflatten lists in the HTML
14474
14540
  * @returns {string} Editor content as HTML
14475
14541
  */
14476
14542
  getHTML({ unflattenLists = false } = {}) {
@@ -14549,85 +14615,90 @@ const _Editor = class _Editor extends EventEmitter {
14549
14615
  getUpdatedDocs = false,
14550
14616
  fieldsHighlightColor = null
14551
14617
  } = {}) {
14552
- const json = __privateMethod(this, _Editor_instances, prepareDocumentForExport_fn).call(this, comments);
14553
- const documentXml = await this.converter.exportToDocx(
14554
- json,
14555
- this.schema,
14556
- this.storage.image.media,
14557
- isFinalDoc,
14558
- commentsType,
14559
- comments,
14560
- this,
14561
- exportJsonOnly,
14562
- fieldsHighlightColor
14563
- );
14564
- __privateMethod(this, _Editor_instances, validateDocumentExport_fn).call(this);
14565
- if (exportXmlOnly || exportJsonOnly) return documentXml;
14566
- const customXml = this.converter.schemaToXml(this.converter.convertedXml["docProps/custom.xml"].elements[0]);
14567
- const styles = this.converter.schemaToXml(this.converter.convertedXml["word/styles.xml"].elements[0]);
14568
- const customSettings = this.converter.schemaToXml(this.converter.convertedXml["word/settings.xml"].elements[0]);
14569
- const rels = this.converter.schemaToXml(this.converter.convertedXml["word/_rels/document.xml.rels"].elements[0]);
14570
- const media = this.converter.addedMedia;
14571
- const updatedHeadersFooters = {};
14572
- Object.entries(this.converter.convertedXml).forEach(([name, json2]) => {
14573
- if (name.includes("header") || name.includes("footer")) {
14574
- const resultXml = this.converter.schemaToXml(json2.elements[0]);
14575
- updatedHeadersFooters[name] = String(resultXml);
14576
- }
14577
- });
14578
- const numberingData = this.converter.convertedXml["word/numbering.xml"];
14579
- const numbering = this.converter.schemaToXml(numberingData.elements[0]);
14580
- const updatedDocs = {
14581
- ...this.options.customUpdatedFiles,
14582
- "word/document.xml": String(documentXml),
14583
- "docProps/custom.xml": String(customXml),
14584
- "word/settings.xml": String(customSettings),
14585
- "word/_rels/document.xml.rels": String(rels),
14586
- "word/numbering.xml": String(numbering),
14587
- // Replace & with &amp; in styles.xml as DOCX viewers can't handle it
14588
- "word/styles.xml": String(styles).replace(/&/gi, "&amp;"),
14589
- ...updatedHeadersFooters
14590
- };
14591
- if (comments.length) {
14592
- const commentsXml = this.converter.schemaToXml(this.converter.convertedXml["word/comments.xml"].elements[0]);
14593
- const commentsExtendedXml = this.converter.schemaToXml(
14594
- this.converter.convertedXml["word/commentsExtended.xml"].elements[0]
14595
- );
14596
- const commentsExtensibleXml = this.converter.schemaToXml(
14597
- this.converter.convertedXml["word/commentsExtensible.xml"].elements[0]
14598
- );
14599
- const commentsIdsXml = this.converter.schemaToXml(
14600
- this.converter.convertedXml["word/commentsIds.xml"].elements[0]
14618
+ try {
14619
+ const json = __privateMethod(this, _Editor_instances, prepareDocumentForExport_fn).call(this, comments);
14620
+ const documentXml = await this.converter.exportToDocx(
14621
+ json,
14622
+ this.schema,
14623
+ this.storage.image.media,
14624
+ isFinalDoc,
14625
+ commentsType,
14626
+ comments,
14627
+ this,
14628
+ exportJsonOnly,
14629
+ fieldsHighlightColor
14601
14630
  );
14602
- updatedDocs["word/comments.xml"] = String(commentsXml);
14603
- updatedDocs["word/commentsExtended.xml"] = String(commentsExtendedXml);
14604
- updatedDocs["word/commentsExtensible.xml"] = String(commentsExtensibleXml);
14605
- updatedDocs["word/commentsIds.xml"] = String(commentsIdsXml);
14606
- }
14607
- const zipper = new DocxZipper();
14608
- if (getUpdatedDocs) {
14609
- updatedDocs["[Content_Types].xml"] = await zipper.updateContentTypes(
14610
- {
14611
- files: this.options.content
14612
- },
14631
+ __privateMethod(this, _Editor_instances, validateDocumentExport_fn).call(this);
14632
+ if (exportXmlOnly || exportJsonOnly) return documentXml;
14633
+ const customXml = this.converter.schemaToXml(this.converter.convertedXml["docProps/custom.xml"].elements[0]);
14634
+ const styles = this.converter.schemaToXml(this.converter.convertedXml["word/styles.xml"].elements[0]);
14635
+ const customSettings = this.converter.schemaToXml(this.converter.convertedXml["word/settings.xml"].elements[0]);
14636
+ const rels = this.converter.schemaToXml(this.converter.convertedXml["word/_rels/document.xml.rels"].elements[0]);
14637
+ const media = this.converter.addedMedia;
14638
+ const updatedHeadersFooters = {};
14639
+ Object.entries(this.converter.convertedXml).forEach(([name, json2]) => {
14640
+ if (name.includes("header") || name.includes("footer")) {
14641
+ const resultXml = this.converter.schemaToXml(json2.elements[0]);
14642
+ updatedHeadersFooters[name] = String(resultXml);
14643
+ }
14644
+ });
14645
+ const numberingData = this.converter.convertedXml["word/numbering.xml"];
14646
+ const numbering = this.converter.schemaToXml(numberingData.elements[0]);
14647
+ const updatedDocs = {
14648
+ ...this.options.customUpdatedFiles,
14649
+ "word/document.xml": String(documentXml),
14650
+ "docProps/custom.xml": String(customXml),
14651
+ "word/settings.xml": String(customSettings),
14652
+ "word/_rels/document.xml.rels": String(rels),
14653
+ "word/numbering.xml": String(numbering),
14654
+ // Replace & with &amp; in styles.xml as DOCX viewers can't handle it
14655
+ "word/styles.xml": String(styles).replace(/&/gi, "&amp;"),
14656
+ ...updatedHeadersFooters
14657
+ };
14658
+ if (comments.length) {
14659
+ const commentsXml = this.converter.schemaToXml(this.converter.convertedXml["word/comments.xml"].elements[0]);
14660
+ const commentsExtendedXml = this.converter.schemaToXml(
14661
+ this.converter.convertedXml["word/commentsExtended.xml"].elements[0]
14662
+ );
14663
+ const commentsExtensibleXml = this.converter.schemaToXml(
14664
+ this.converter.convertedXml["word/commentsExtensible.xml"].elements[0]
14665
+ );
14666
+ const commentsIdsXml = this.converter.schemaToXml(
14667
+ this.converter.convertedXml["word/commentsIds.xml"].elements[0]
14668
+ );
14669
+ updatedDocs["word/comments.xml"] = String(commentsXml);
14670
+ updatedDocs["word/commentsExtended.xml"] = String(commentsExtendedXml);
14671
+ updatedDocs["word/commentsExtensible.xml"] = String(commentsExtensibleXml);
14672
+ updatedDocs["word/commentsIds.xml"] = String(commentsIdsXml);
14673
+ }
14674
+ const zipper = new DocxZipper();
14675
+ if (getUpdatedDocs) {
14676
+ updatedDocs["[Content_Types].xml"] = await zipper.updateContentTypes(
14677
+ {
14678
+ files: this.options.content
14679
+ },
14680
+ media,
14681
+ true
14682
+ );
14683
+ return updatedDocs;
14684
+ }
14685
+ const result = await zipper.updateZip({
14686
+ docx: this.options.content,
14687
+ updatedDocs,
14688
+ originalDocxFile: this.options.fileSource,
14613
14689
  media,
14614
- true
14615
- );
14616
- return updatedDocs;
14690
+ fonts: this.options.fonts,
14691
+ isHeadless: this.options.isHeadless
14692
+ });
14693
+ this.options.telemetry?.trackUsage("document_export", {
14694
+ documentType: "docx",
14695
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
14696
+ });
14697
+ return result;
14698
+ } catch (error) {
14699
+ this.emit("exception", { error, editor: this });
14700
+ console.error(error);
14617
14701
  }
14618
- const result = await zipper.updateZip({
14619
- docx: this.options.content,
14620
- updatedDocs,
14621
- originalDocxFile: this.options.fileSource,
14622
- media,
14623
- fonts: this.options.fonts,
14624
- isHeadless: this.options.isHeadless
14625
- });
14626
- this.options.telemetry?.trackUsage("document_export", {
14627
- documentType: "docx",
14628
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
14629
- });
14630
- return result;
14631
14702
  }
14632
14703
  /**
14633
14704
  * Destroy the editor and clean up resources
@@ -14648,7 +14719,9 @@ const _Editor = class _Editor extends EventEmitter {
14648
14719
  }
14649
14720
  this.converter.headerEditors.length = 0;
14650
14721
  this.converter.footerEditors.length = 0;
14651
- } catch {
14722
+ } catch (error) {
14723
+ this.emit("exception", { error, editor: this });
14724
+ console.error(error);
14652
14725
  }
14653
14726
  }
14654
14727
  /**
@@ -14668,7 +14741,7 @@ const _Editor = class _Editor extends EventEmitter {
14668
14741
  * @returns {Object | void} Migration results
14669
14742
  */
14670
14743
  processCollaborationMigrations() {
14671
- console.debug("[checkVersionMigrations] Current editor version", "0.18.1");
14744
+ console.debug("[checkVersionMigrations] Current editor version", "0.20.0");
14672
14745
  if (!this.options.ydoc) return;
14673
14746
  const metaMap = this.options.ydoc.getMap("meta");
14674
14747
  let docVersion = metaMap.get("version");
@@ -14713,7 +14786,7 @@ const _Editor = class _Editor extends EventEmitter {
14713
14786
  this.initDefaultStyles();
14714
14787
  if (this.options.ydoc && this.options.collaborationProvider) {
14715
14788
  updateYdocDocxData(this);
14716
- this.initializeCollaborationData(true);
14789
+ this.initializeCollaborationData();
14717
14790
  } else {
14718
14791
  __privateMethod(this, _Editor_instances, insertNewFileData_fn).call(this);
14719
14792
  }
@@ -14882,7 +14955,6 @@ init_fn = function() {
14882
14955
  this.on("beforeCreate", this.options.onBeforeCreate);
14883
14956
  this.emit("beforeCreate", { editor: this });
14884
14957
  this.on("contentError", this.options.onContentError);
14885
- this.on("exception", this.options.onException);
14886
14958
  this.mount(this.options.element);
14887
14959
  this.on("create", this.options.onCreate);
14888
14960
  this.on("update", this.options.onUpdate);
@@ -14900,11 +14972,14 @@ init_fn = function() {
14900
14972
  this.on("paginationUpdate", this.options.onPaginationUpdate);
14901
14973
  this.on("comment-positions", this.options.onCommentLocationsUpdate);
14902
14974
  this.on("list-definitions-change", this.options.onListDefinitionsChange);
14975
+ this.on("exception", this.options.onException);
14903
14976
  if (!this.options.isHeadless) {
14904
14977
  this.initializeCollaborationData();
14905
14978
  this.initDefaultStyles();
14906
14979
  }
14907
- if (!this.options.ydoc) this.migrateListsToV2();
14980
+ if (!this.options.ydoc || this.options.markdown || this.options.html) {
14981
+ this.migrateListsToV2();
14982
+ }
14908
14983
  this.setDocumentMode(this.options.documentMode);
14909
14984
  if (!this.options.ydoc) {
14910
14985
  if (!this.options.isChildEditor) {
@@ -14914,6 +14989,7 @@ init_fn = function() {
14914
14989
  }
14915
14990
  }
14916
14991
  __privateMethod(this, _Editor_instances, initDevTools_fn).call(this);
14992
+ __privateMethod(this, _Editor_instances, registerCopyHandler_fn).call(this);
14917
14993
  };
14918
14994
  /**
14919
14995
  * Initialize the editor in rich text mode
@@ -14969,6 +15045,21 @@ checkHeadless_fn = function(options) {
14969
15045
  global.window = options.mockWindow;
14970
15046
  }
14971
15047
  };
15048
+ registerCopyHandler_fn = function() {
15049
+ this.view.dom.addEventListener("copy", (event) => {
15050
+ const clipboardData = event.clipboardData;
15051
+ if (!clipboardData) return;
15052
+ event.preventDefault();
15053
+ const { from: from2, to } = this.view.state.selection;
15054
+ const slice2 = this.view.state.doc.slice(from2, to);
15055
+ const fragment = slice2.content;
15056
+ const div2 = document.createElement("div");
15057
+ const serializer = DOMSerializer.fromSchema(this.view.state.schema);
15058
+ div2.appendChild(serializer.serializeFragment(fragment));
15059
+ const html = transformListsInCopiedContent(div2.innerHTML);
15060
+ clipboardData.setData("text/html", html);
15061
+ });
15062
+ };
14972
15063
  /**
14973
15064
  * Replace the current document with new data. Necessary for initializing a new collaboration file,
14974
15065
  * since we need to insert the data only after the provider has synced.
@@ -15052,8 +15143,8 @@ initMedia_fn = function() {
15052
15143
  if (!this.options.ydoc) return this.storage.image.media = this.options.mediaFiles;
15053
15144
  const mediaMap = this.options.ydoc.getMap("media");
15054
15145
  if (this.options.isNewFile) {
15055
- Object.entries(this.options.mediaFiles).forEach(([key, value]) => {
15056
- mediaMap.set(key, value);
15146
+ Object.entries(this.options.mediaFiles).forEach(([key2, value]) => {
15147
+ mediaMap.set(key2, value);
15057
15148
  });
15058
15149
  this.storage.image.media = this.options.mediaFiles;
15059
15150
  } else {
@@ -15326,7 +15417,9 @@ endCollaboration_fn = function() {
15326
15417
  console.debug("🔗 [super-editor] Ending collaboration");
15327
15418
  if (this.options.collaborationProvider) this.options.collaborationProvider.disconnect();
15328
15419
  if (this.options.ydoc) this.options.ydoc.destroy();
15329
- } catch {
15420
+ } catch (error) {
15421
+ this.emit("exception", { error, editor: this });
15422
+ console.error(error);
15330
15423
  }
15331
15424
  };
15332
15425
  /**
@@ -15361,11 +15454,6 @@ const Color = Extension.create({
15361
15454
  name: "color",
15362
15455
  addOptions() {
15363
15456
  return {
15364
- /**
15365
- * @typedef {Object} ColorOptions
15366
- * @category Options
15367
- * @property {string[]} [types=['textStyle']] - Mark types to add color support to
15368
- */
15369
15457
  types: ["textStyle"]
15370
15458
  };
15371
15459
  },
@@ -15374,10 +15462,6 @@ const Color = Extension.create({
15374
15462
  {
15375
15463
  types: this.options.types,
15376
15464
  attributes: {
15377
- /**
15378
- * @category Attribute
15379
- * @param {ColorValue} [color] - Text color value
15380
- */
15381
15465
  color: {
15382
15466
  default: null,
15383
15467
  parseDOM: (el) => el.style.color?.replace(/['"]+/g, ""),
@@ -15396,16 +15480,17 @@ const Color = Extension.create({
15396
15480
  * Set text color
15397
15481
  * @category Command
15398
15482
  * @param {ColorValue} color - Color value to apply
15399
- * @returns {Function} Command function
15400
15483
  * @example
15401
15484
  * // Set to red using hex
15402
- * setColor('#ff0000')
15485
+ * editor.commands.setColor('#ff0000')
15403
15486
  *
15487
+ * @example
15404
15488
  * // Set using rgb
15405
- * setColor('rgb(255, 0, 0)')
15489
+ * editor.commands.setColor('rgb(255, 0, 0)')
15406
15490
  *
15491
+ * @example
15407
15492
  * // Set using named color
15408
- * setColor('blue')
15493
+ * editor.commands.setColor('blue')
15409
15494
  * @note Preserves other text styling attributes
15410
15495
  */
15411
15496
  setColor: (color) => ({ chain }) => {
@@ -15414,9 +15499,8 @@ const Color = Extension.create({
15414
15499
  /**
15415
15500
  * Remove text color
15416
15501
  * @category Command
15417
- * @returns {Function} Command function
15418
15502
  * @example
15419
- * unsetColor()
15503
+ * editor.commands.unsetColor()
15420
15504
  * @note Removes color while preserving other text styles
15421
15505
  */
15422
15506
  unsetColor: () => ({ chain }) => {
@@ -15429,11 +15513,6 @@ const FontFamily = Extension.create({
15429
15513
  name: "fontFamily",
15430
15514
  addOptions() {
15431
15515
  return {
15432
- /**
15433
- * @typedef {Object} FontFamilyOptions
15434
- * @category Options
15435
- * @property {string[]} [types=['textStyle']] - Mark types to add font family support to
15436
- */
15437
15516
  types: ["textStyle"]
15438
15517
  };
15439
15518
  },
@@ -15442,10 +15521,6 @@ const FontFamily = Extension.create({
15442
15521
  {
15443
15522
  types: this.options.types,
15444
15523
  attributes: {
15445
- /**
15446
- * @category Attribute
15447
- * @param {FontFamilyValue} [fontFamily] - Font family for text
15448
- */
15449
15524
  fontFamily: {
15450
15525
  default: null,
15451
15526
  parseDOM: (el) => el.style.fontFamily?.replace(/['"]+/g, ""),
@@ -15464,13 +15539,13 @@ const FontFamily = Extension.create({
15464
15539
  * Set font family
15465
15540
  * @category Command
15466
15541
  * @param {FontFamilyValue} fontFamily - Font family to apply
15467
- * @returns {Function} Command function
15468
15542
  * @example
15469
15543
  * // Set to Arial
15470
- * setFontFamily('Arial')
15544
+ * editor.commands.setFontFamily('Arial')
15471
15545
  *
15546
+ * @example
15472
15547
  * // Set to serif font
15473
- * setFontFamily('Georgia, serif')
15548
+ * editor.commands.setFontFamily('Georgia, serif')
15474
15549
  * @note Preserves other text styling attributes
15475
15550
  */
15476
15551
  setFontFamily: (fontFamily) => ({ chain }) => {
@@ -15479,9 +15554,8 @@ const FontFamily = Extension.create({
15479
15554
  /**
15480
15555
  * Remove font family
15481
15556
  * @category Command
15482
- * @returns {Function} Command function
15483
15557
  * @example
15484
- * unsetFontFamily()
15558
+ * editor.commands.unsetFontFamily()
15485
15559
  * @note Reverts to default document font
15486
15560
  */
15487
15561
  unsetFontFamily: () => ({ chain }) => {
@@ -15494,12 +15568,6 @@ const FontSize = Extension.create({
15494
15568
  name: "fontSize",
15495
15569
  addOptions() {
15496
15570
  return {
15497
- /**
15498
- * @typedef {Object} FontSizeOptions
15499
- * @category Options
15500
- * @property {string[]} [types=['textStyle', 'tableCell']] - Node/mark types to add font size support to
15501
- * @property {FontSizeDefaults} [defaults] - Default size configuration
15502
- */
15503
15571
  types: ["textStyle", "tableCell"],
15504
15572
  defaults: {
15505
15573
  value: 12,
@@ -15514,10 +15582,6 @@ const FontSize = Extension.create({
15514
15582
  {
15515
15583
  types: this.options.types,
15516
15584
  attributes: {
15517
- /**
15518
- * @category Attribute
15519
- * @param {FontSizeValue} [fontSize] - Font size with unit
15520
- */
15521
15585
  fontSize: {
15522
15586
  default: null,
15523
15587
  parseDOM: (el) => el.style.fontSize,
@@ -15539,16 +15603,10 @@ const FontSize = Extension.create({
15539
15603
  * Set font size
15540
15604
  * @category Command
15541
15605
  * @param {FontSizeValue} fontSize - Size to apply (with optional unit)
15542
- * @returns {Function} Command function
15543
15606
  * @example
15544
- * // Set to 14pt
15545
- * setFontSize('14pt')
15546
- *
15547
- * // Set to 18px
15548
- * setFontSize('18px')
15549
- *
15550
- * // Set without unit (uses default)
15551
- * setFontSize(16)
15607
+ * editor.commands.setFontSize('14pt')
15608
+ * editor.commands.setFontSize('18px')
15609
+ * editor.commands.setFontSize(16)
15552
15610
  * @note Automatically clamps to min/max values
15553
15611
  */
15554
15612
  setFontSize: (fontSize) => ({ chain }) => {
@@ -15570,9 +15628,8 @@ const FontSize = Extension.create({
15570
15628
  /**
15571
15629
  * Remove font size
15572
15630
  * @category Command
15573
- * @returns {Function} Command function
15574
15631
  * @example
15575
- * unsetFontSize()
15632
+ * editor.commands.unsetFontSize()
15576
15633
  * @note Reverts to default document size
15577
15634
  */
15578
15635
  unsetFontSize: () => ({ chain }) => {
@@ -15622,13 +15679,9 @@ const TextAlign = Extension.create({
15622
15679
  * Set text alignment
15623
15680
  * @category Command
15624
15681
  * @param {string} alignment - Alignment value (left, center, right, justify)
15625
- * @returns {Function} Command function
15626
15682
  * @example
15627
- * // Set to center
15628
- * setTextAlign('center')
15629
- *
15630
- * // Set to justify
15631
- * setTextAlign('justify')
15683
+ * editor.commands.setTextAlign('center')
15684
+ * editor.commands.setTextAlign('justify')
15632
15685
  * @note Applies to all configured node types (heading, paragraph by default)
15633
15686
  */
15634
15687
  setTextAlign: (alignment) => ({ commands: commands2 }) => {
@@ -15639,9 +15692,8 @@ const TextAlign = Extension.create({
15639
15692
  /**
15640
15693
  * Remove text alignment (reset to default)
15641
15694
  * @category Command
15642
- * @returns {Function} Command function
15643
15695
  * @example
15644
- * unsetTextAlign()
15696
+ * editor.commands.unsetTextAlign()
15645
15697
  * @note Resets alignment to the default value
15646
15698
  */
15647
15699
  unsetTextAlign: () => ({ commands: commands2 }) => {
@@ -15782,13 +15834,6 @@ const LineHeight = Extension.create({
15782
15834
  name: "lineHeight",
15783
15835
  addOptions() {
15784
15836
  return {
15785
- /**
15786
- * @typedef {Object} LineHeightOptions
15787
- * @category Options
15788
- * @property {string[]} [types=['heading', 'paragraph']] - Block types to add line height support to
15789
- * @property {Object} [defaults] - Default configuration
15790
- * @property {string} [defaults.unit=''] - Default unit for line height values
15791
- */
15792
15837
  types: ["heading", "paragraph"],
15793
15838
  defaults: {
15794
15839
  unit: ""
@@ -15800,10 +15845,6 @@ const LineHeight = Extension.create({
15800
15845
  {
15801
15846
  types: this.options.types,
15802
15847
  attributes: {
15803
- /**
15804
- * @category Attribute
15805
- * @param {LineHeightValue} [lineHeight] - Line height value
15806
- */
15807
15848
  lineHeight: {
15808
15849
  default: null,
15809
15850
  parseDOM: (el) => el.style.lineHeight,
@@ -15829,16 +15870,10 @@ const LineHeight = Extension.create({
15829
15870
  * Set line height for blocks
15830
15871
  * @category Command
15831
15872
  * @param {LineHeightValue} lineHeight - Line height to apply
15832
- * @returns {Function} Command function
15833
15873
  * @example
15834
- * // Set to 1.5x spacing
15835
- * setLineHeight(1.5)
15836
- *
15837
- * // Set to 24px spacing
15838
- * setLineHeight('24px')
15839
- *
15840
- * // Set to double spacing
15841
- * setLineHeight(2)
15874
+ * editor.commands.setLineHeight(1.5)
15875
+ * editor.commands.setLineHeight('24px')
15876
+ * editor.commands.setLineHeight(2)
15842
15877
  * @note Applies to paragraphs and headings
15843
15878
  */
15844
15879
  setLineHeight: (lineHeight) => ({ commands: commands2 }) => {
@@ -15848,9 +15883,8 @@ const LineHeight = Extension.create({
15848
15883
  /**
15849
15884
  * Remove line height
15850
15885
  * @category Command
15851
- * @returns {Function} Command function
15852
15886
  * @example
15853
- * unsetLineHeight()
15887
+ * editor.commands.unsetLineHeight()
15854
15888
  * @note Reverts to default line spacing
15855
15889
  */
15856
15890
  unsetLineHeight: () => ({ commands: commands2 }) => {
@@ -15878,9 +15912,8 @@ const FormatCommands = Extension.create({
15878
15912
  /**
15879
15913
  * Clear all formatting (nodes and marks)
15880
15914
  * @category Command
15881
- * @returns {Function} Command function
15882
15915
  * @example
15883
- * clearFormat()
15916
+ * editor.commands.clearFormat()
15884
15917
  * @note Removes all marks and resets nodes to default paragraph
15885
15918
  */
15886
15919
  clearFormat: () => ({ chain }) => {
@@ -15889,9 +15922,8 @@ const FormatCommands = Extension.create({
15889
15922
  /**
15890
15923
  * Clear only mark formatting
15891
15924
  * @category Command
15892
- * @returns {Function} Command function
15893
15925
  * @example
15894
- * clearMarksFormat()
15926
+ * editor.commands.clearMarksFormat()
15895
15927
  * @note Removes bold, italic, underline, colors, etc. but preserves block structure
15896
15928
  */
15897
15929
  clearMarksFormat: () => ({ chain }) => {
@@ -15900,9 +15932,8 @@ const FormatCommands = Extension.create({
15900
15932
  /**
15901
15933
  * Clear only node formatting
15902
15934
  * @category Command
15903
- * @returns {Function} Command function
15904
15935
  * @example
15905
- * clearNodesFormat()
15936
+ * editor.commands.clearNodesFormat()
15906
15937
  * @note Converts headings, lists, etc. to paragraphs but preserves text marks
15907
15938
  */
15908
15939
  clearNodesFormat: () => ({ chain }) => {
@@ -15911,13 +15942,8 @@ const FormatCommands = Extension.create({
15911
15942
  /**
15912
15943
  * Copy format from selection or apply copied format
15913
15944
  * @category Command
15914
- * @returns {Function} Command function
15915
15945
  * @example
15916
- * // First call: copy format from selection
15917
- * copyFormat()
15918
- *
15919
- * // Second call: apply copied format to new selection
15920
- * copyFormat()
15946
+ * editor.commands.copyFormat()
15921
15947
  * @note Works like format painter - first click copies, second click applies
15922
15948
  */
15923
15949
  copyFormat: () => ({ chain }) => {
@@ -15936,11 +15962,11 @@ const FormatCommands = Extension.create({
15936
15962
  const { type, attrs } = mark;
15937
15963
  const { name } = type;
15938
15964
  if (name === "textStyle") {
15939
- Object.keys(attrs).forEach((key) => {
15940
- if (!attrs[key]) return;
15965
+ Object.keys(attrs).forEach((key2) => {
15966
+ if (!attrs[key2]) return;
15941
15967
  const attributes = {};
15942
- attributes[key] = attrs[key];
15943
- processedMarks.push({ name: key, attrs: attributes });
15968
+ attributes[key2] = attrs[key2];
15969
+ processedMarks.push({ name: key2, attrs: attributes });
15944
15970
  });
15945
15971
  } else {
15946
15972
  processedMarks.push({ name, attrs });
@@ -15955,13 +15981,13 @@ const FormatCommands = Extension.create({
15955
15981
  fontFamily: ["setFontFamily", "unsetFontFamily"]
15956
15982
  };
15957
15983
  let result = chain();
15958
- Object.keys(marksToCommands).forEach((key) => {
15959
- const [setCommand, unsetCommand, defaultParam] = marksToCommands[key];
15960
- const markToApply = processedMarks.find((mark) => mark.name === key);
15961
- const hasEmptyAttrs = markToApply?.attrs && markToApply?.attrs[key];
15984
+ Object.keys(marksToCommands).forEach((key2) => {
15985
+ const [setCommand, unsetCommand, defaultParam] = marksToCommands[key2];
15986
+ const markToApply = processedMarks.find((mark) => mark.name === key2);
15987
+ const hasEmptyAttrs = markToApply?.attrs && markToApply?.attrs[key2];
15962
15988
  let cmd = {};
15963
15989
  if (!markToApply && !hasEmptyAttrs) cmd = { command: unsetCommand, argument: defaultParam };
15964
- else cmd = { command: setCommand, argument: markToApply.attrs[key] || defaultParam };
15990
+ else cmd = { command: setCommand, argument: markToApply.attrs[key2] || defaultParam };
15965
15991
  result = result[cmd.command](cmd.argument);
15966
15992
  });
15967
15993
  this.storage.storedStyle = null;
@@ -16330,6 +16356,9 @@ function drawGapCursor(state) {
16330
16356
  }
16331
16357
  const Gapcursor = Extension.create({
16332
16358
  name: "gapCursor",
16359
+ addOptions() {
16360
+ return {};
16361
+ },
16333
16362
  addPmPlugins() {
16334
16363
  return [gapCursor()];
16335
16364
  },
@@ -16670,6 +16699,9 @@ function getCursorPositionRelativeToContainer(view, eventLocation) {
16670
16699
  const SlashMenuPluginKey = new PluginKey("slashMenu");
16671
16700
  const SlashMenu = Extension.create({
16672
16701
  name: "slashMenu",
16702
+ addOptions() {
16703
+ return {};
16704
+ },
16673
16705
  addPmPlugins() {
16674
16706
  if (this.editor.options?.disableContextMenu) {
16675
16707
  return [];
@@ -16807,11 +16839,6 @@ const Document = Node$1.create({
16807
16839
  },
16808
16840
  addAttributes() {
16809
16841
  return {
16810
- /**
16811
- * @private
16812
- * @category Attribute
16813
- * @param {Object} [attributes] - Internal document attributes
16814
- */
16815
16842
  attributes: {
16816
16843
  rendered: false,
16817
16844
  "aria-label": "Document node"
@@ -16823,10 +16850,10 @@ const Document = Node$1.create({
16823
16850
  /**
16824
16851
  * Get document statistics
16825
16852
  * @category Command
16826
- * @returns {Function} Command function
16827
16853
  * @example
16828
16854
  * // Get word and character count
16829
- * getDocumentStats()
16855
+ * const stats = editor.commands.getDocumentStats()
16856
+ * console.log(`${stats.words} words, ${stats.characters} characters`)
16830
16857
  * @note Returns word count, character count, and paragraph count
16831
16858
  */
16832
16859
  getDocumentStats: () => ({ editor }) => {
@@ -16843,9 +16870,8 @@ const Document = Node$1.create({
16843
16870
  /**
16844
16871
  * Clear entire document
16845
16872
  * @category Command
16846
- * @returns {Function} Command function
16847
16873
  * @example
16848
- * clearDocument()
16874
+ * editor.commands.clearDocument()
16849
16875
  * @note Replaces all content with an empty paragraph
16850
16876
  */
16851
16877
  clearDocument: () => ({ commands: commands2 }) => {
@@ -16857,13 +16883,19 @@ const Document = Node$1.create({
16857
16883
  const Text = Node$1.create({
16858
16884
  name: "text",
16859
16885
  group: "inline",
16860
- inline: true
16886
+ inline: true,
16887
+ addOptions() {
16888
+ return {};
16889
+ }
16861
16890
  });
16862
16891
  const RunItem = Node$1.create({
16863
16892
  name: "run",
16864
16893
  group: "inline",
16865
16894
  content: "text*",
16866
16895
  inline: true,
16896
+ addOptions() {
16897
+ return {};
16898
+ },
16867
16899
  parseDOM() {
16868
16900
  return [{ tag: "run" }];
16869
16901
  },
@@ -16889,14 +16921,6 @@ const BulletList = Node$1.create({
16889
16921
  },
16890
16922
  addOptions() {
16891
16923
  return {
16892
- /**
16893
- * @typedef {Object} BulletListOptions
16894
- * @category Options
16895
- * @property {string} [itemTypeName='listItem'] - Name of the list item node type
16896
- * @property {Object} [htmlAttributes] - HTML attributes for the ul element
16897
- * @property {boolean} [keepMarks=true] - Whether to preserve marks when splitting
16898
- * @property {boolean} [keepAttributes=false] - Whether to preserve attributes when splitting
16899
- */
16900
16924
  itemTypeName: "listItem",
16901
16925
  htmlAttributes: {
16902
16926
  "aria-label": "Bullet list node"
@@ -16914,27 +16938,13 @@ const BulletList = Node$1.create({
16914
16938
  },
16915
16939
  addAttributes() {
16916
16940
  return {
16917
- /**
16918
- * @category Attribute
16919
- * @param {string} [list-style-type='bullet'] - List style type for this list
16920
- */
16921
16941
  "list-style-type": {
16922
16942
  default: "bullet",
16923
16943
  rendered: false
16924
16944
  },
16925
- /**
16926
- * @private
16927
- * @category Attribute
16928
- * @param {string} [listId] - Internal list identifier for numbering
16929
- */
16930
16945
  listId: {
16931
16946
  rendered: false
16932
16947
  },
16933
- /**
16934
- * @private
16935
- * @category Attribute
16936
- * @param {string} [sdBlockId] - Internal block tracking ID
16937
- */
16938
16948
  sdBlockId: {
16939
16949
  default: null,
16940
16950
  keepOnSplit: false,
@@ -16943,11 +16953,6 @@ const BulletList = Node$1.create({
16943
16953
  return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
16944
16954
  }
16945
16955
  },
16946
- /**
16947
- * @private
16948
- * @category Attribute
16949
- * @param {Object} [attributes] - Additional attributes for the list
16950
- */
16951
16956
  attributes: {
16952
16957
  rendered: false,
16953
16958
  keepOnSplit: true
@@ -16959,10 +16964,9 @@ const BulletList = Node$1.create({
16959
16964
  /**
16960
16965
  * Toggle a bullet list at the current selection
16961
16966
  * @category Command
16962
- * @returns {Function} Command function
16963
16967
  * @example
16964
16968
  * // Toggle bullet list on selected text
16965
- * toggleBulletList()
16969
+ * editor.commands.toggleBulletList()
16966
16970
  * @note Converts selected paragraphs to list items or removes list formatting
16967
16971
  */
16968
16972
  toggleBulletList: () => (params2) => {
@@ -17081,9 +17085,25 @@ const OrderedList = Node$1.create({
17081
17085
  },
17082
17086
  addCommands() {
17083
17087
  return {
17088
+ /**
17089
+ * Toggle ordered list formatting
17090
+ * @category Command
17091
+ * @example
17092
+ * editor.commands.toggleOrderedList()
17093
+ * @note Converts selection to ordered list or back to paragraphs
17094
+ */
17084
17095
  toggleOrderedList: () => (params2) => {
17085
17096
  return toggleList(this.type)(params2);
17086
17097
  },
17098
+ /**
17099
+ * Restart list node numbering
17100
+ * @category Command
17101
+ * @param {Array} followingNodes - Nodes to restart
17102
+ * @param {number} pos - Starting position
17103
+ * @example
17104
+ * editor.commands.restartListNodes(nodes, position)
17105
+ * @note Resets list numbering for specified nodes
17106
+ */
17087
17107
  restartListNodes: (followingNodes, pos) => ({ tr }) => {
17088
17108
  let currentNodePos = pos;
17089
17109
  const nodes = followingNodes.map((node) => {
@@ -17102,8 +17122,11 @@ const OrderedList = Node$1.create({
17102
17122
  return true;
17103
17123
  },
17104
17124
  /**
17105
- * Updates ordered list style type when sink or lift `listItem`.
17106
- * @example 1,2,3 -> a,b,c -> i,ii,iii -> 1,2,3 -> etc
17125
+ * Update ordered list style type based on nesting level
17126
+ * @category Command
17127
+ * @example
17128
+ * editor.commands.updateOrderedListStyleType()
17129
+ * @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
17107
17130
  */
17108
17131
  updateOrderedListStyleType: () => ({ dispatch, tr }) => {
17109
17132
  let list = findParentNode((node) => node.type.name === this.name)(tr.selection);
@@ -17380,7 +17403,7 @@ const CustomSelection = Extension.create({
17380
17403
  * @returns {Function} Command function
17381
17404
  * @example
17382
17405
  * // Restore selection after toolbar interaction
17383
- * restorePreservedSelection()
17406
+ * editor.commands.restorePreservedSelection()
17384
17407
  * @note Used internally to maintain selection when interacting with toolbar
17385
17408
  */
17386
17409
  restorePreservedSelection: () => ({ tr, state }) => {
@@ -17465,7 +17488,7 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17465
17488
  resultStyles["text-transform"] = basedOnDefinitionStyles["text-transform"];
17466
17489
  }
17467
17490
  Object.entries(resultStyles).forEach(([k, value]) => {
17468
- const key = kebabCase(k);
17491
+ const key2 = kebabCase(k);
17469
17492
  const flattenedMarks = [];
17470
17493
  node?.marks?.forEach((n) => {
17471
17494
  if (n.type.name === "textStyle") {
@@ -17476,46 +17499,46 @@ const generateLinkedStyleString = (linkedStyle, basedOnStyle, node, parent, incl
17476
17499
  });
17477
17500
  return;
17478
17501
  }
17479
- flattenedMarks.push({ key: n.type.name, value: n.attrs[key] });
17502
+ flattenedMarks.push({ key: n.type.name, value: n.attrs[key2] });
17480
17503
  });
17481
- const mark = flattenedMarks.find((n) => n.key === key);
17504
+ const mark = flattenedMarks.find((n) => n.key === key2);
17482
17505
  const hasParentIndent = Object.keys(parent?.attrs?.indent || {});
17483
17506
  const hasParentSpacing = Object.keys(parent?.attrs?.spacing || {});
17484
17507
  const listTypes = ["orderedList", "listItem"];
17485
17508
  if (!mark) {
17486
- if (key === "spacing" && includeSpacing && !hasParentSpacing) {
17509
+ if (key2 === "spacing" && includeSpacing && !hasParentSpacing) {
17487
17510
  const space = getSpacingStyle(value);
17488
17511
  Object.entries(space).forEach(([k2, v]) => {
17489
17512
  markValue[k2] = v;
17490
17513
  });
17491
- } else if (key === "indent" && includeSpacing && !hasParentIndent) {
17514
+ } else if (key2 === "indent" && includeSpacing && !hasParentIndent) {
17492
17515
  const { leftIndent, rightIndent, firstLine } = value;
17493
17516
  if (leftIndent) markValue["margin-left"] = leftIndent + "px";
17494
17517
  if (rightIndent) markValue["margin-right"] = rightIndent + "px";
17495
17518
  if (firstLine) markValue["text-indent"] = firstLine + "px";
17496
- } else if (key === "bold" && node) {
17519
+ } else if (key2 === "bold" && node) {
17497
17520
  const val = value?.value;
17498
17521
  if (!listTypes.includes(node.type.name) && val !== "0") {
17499
17522
  markValue["font-weight"] = "bold";
17500
17523
  }
17501
- } else if (key === "text-transform" && node) {
17524
+ } else if (key2 === "text-transform" && node) {
17502
17525
  if (!listTypes.includes(node.type.name)) {
17503
- markValue[key] = value;
17526
+ markValue[key2] = value;
17504
17527
  }
17505
- } else if (key === "font-size" && node) {
17528
+ } else if (key2 === "font-size" && node) {
17506
17529
  if (!listTypes.includes(node.type.name)) {
17507
- markValue[key] = value;
17530
+ markValue[key2] = value;
17508
17531
  }
17509
- } else if (key === "color" && node) {
17532
+ } else if (key2 === "color" && node) {
17510
17533
  if (!listTypes.includes(node.type.name)) {
17511
- markValue[key] = value;
17534
+ markValue[key2] = value;
17512
17535
  }
17513
17536
  } else if (typeof value === "string") {
17514
- markValue[key] = value;
17537
+ markValue[key2] = value;
17515
17538
  }
17516
17539
  }
17517
17540
  });
17518
- const final = Object.entries(markValue).map(([key, value]) => `${key}: ${value}`).join(";");
17541
+ const final = Object.entries(markValue).map(([key2, value]) => `${key2}: ${value}`).join(";");
17519
17542
  return final;
17520
17543
  };
17521
17544
  const applyLinkedStyleToTransaction = (tr, editor, style) => {
@@ -17669,6 +17692,9 @@ const LinkedStyles = Extension.create({
17669
17692
  name: "linkedStyles",
17670
17693
  priority: 1,
17671
17694
  // We need this plugin to run before the list plugins
17695
+ addOptions() {
17696
+ return {};
17697
+ },
17672
17698
  addPmPlugins() {
17673
17699
  return [createLinkedStylesPlugin(this.editor)];
17674
17700
  },
@@ -17677,11 +17703,10 @@ const LinkedStyles = Extension.create({
17677
17703
  /**
17678
17704
  * Apply a linked style to the selected paragraphs
17679
17705
  * @category Command
17680
- * @param {Object} style - The style object to apply
17681
- * @returns {Function} Command function
17706
+ * @param {LinkedStyle} style - The style object to apply
17682
17707
  * @example
17683
17708
  * const style = editor.helpers.linkedStyles.getStyleById('Heading1');
17684
- * setLinkedStyle(style);
17709
+ * editor.commands.setLinkedStyle(style);
17685
17710
  * @note Clears existing formatting when applying a style
17686
17711
  * @note Works with custom selection preservation
17687
17712
  */
@@ -17692,16 +17717,12 @@ const LinkedStyles = Extension.create({
17692
17717
  /**
17693
17718
  * Toggle a linked style on the current selection
17694
17719
  * @category Command
17695
- * @param {Object} style - The linked style to apply (with id property)
17720
+ * @param {LinkedStyle} style - The linked style to apply (with id property)
17696
17721
  * @param {string|null} [nodeType=null] - Node type to restrict toggle to (e.g., 'paragraph')
17697
- * @returns {Function} Command function
17698
17722
  * @example
17699
- * // Toggle a heading style
17700
17723
  * const style = editor.helpers.linkedStyles.getStyleById('Heading1');
17701
- * toggleLinkedStyle(style)
17702
- *
17703
- * // Toggle only on paragraph nodes
17704
- * toggleLinkedStyle(style, 'paragraph')
17724
+ * editor.commands.toggleLinkedStyle(style)
17725
+ * editor.commands.toggleLinkedStyle(style, 'paragraph')
17705
17726
  * @note If selection is empty, returns false
17706
17727
  * @note Removes style if already applied, applies it if not
17707
17728
  */
@@ -17729,13 +17750,9 @@ const LinkedStyles = Extension.create({
17729
17750
  * Apply a linked style by its ID
17730
17751
  * @category Command
17731
17752
  * @param {string} styleId - The style ID to apply (e.g., 'Heading1')
17732
- * @returns {Function} Command function
17733
17753
  * @example
17734
- * // Apply a heading style
17735
- * setStyleById('Heading1')
17736
- *
17737
- * // Apply a normal style
17738
- * setStyleById('Normal')
17754
+ * editor.commands.setStyleById('Heading1')
17755
+ * editor.commands.setStyleById('Normal')
17739
17756
  * @note Looks up the style from loaded Word styles
17740
17757
  */
17741
17758
  setStyleById: (styleId) => (params2) => {
@@ -18210,7 +18227,7 @@ function orderedListSync(editor) {
18210
18227
  listNumberingType,
18211
18228
  customFormat
18212
18229
  };
18213
- const keysChanged = Object.keys(updatedAttrs).some((key) => node.attrs[key] !== updatedAttrs[key]);
18230
+ const keysChanged = Object.keys(updatedAttrs).some((key2) => node.attrs[key2] !== updatedAttrs[key2]);
18214
18231
  if (keysChanged) {
18215
18232
  tr.setNodeMarkup(pos, void 0, updatedAttrs);
18216
18233
  }
@@ -18443,12 +18460,6 @@ const Paragraph = OxmlNode.create({
18443
18460
  inline: false,
18444
18461
  addOptions() {
18445
18462
  return {
18446
- /**
18447
- * @typedef {Object} HeadingOptions
18448
- * @category Options
18449
- * @property {number[]} [headingLevels=[1,2,3,4,5,6]] - Supported heading levels
18450
- * @property {Object} [htmlAttributes] - HTML attributes for paragraph elements
18451
- */
18452
18463
  headingLevels: [1, 2, 3, 4, 5, 6],
18453
18464
  htmlAttributes: {}
18454
18465
  };
@@ -18596,13 +18607,30 @@ const Paragraph = OxmlNode.create({
18596
18607
  {
18597
18608
  tag: "p",
18598
18609
  getAttrs: (node) => {
18599
- let extra = {};
18610
+ const { styleid, ...extraAttrs } = Array.from(node.attributes).reduce((acc, attr) => {
18611
+ acc[attr.name] = attr.value;
18612
+ return acc;
18613
+ }, {});
18614
+ return {
18615
+ styleId: styleid || null,
18616
+ extraAttrs
18617
+ };
18618
+ }
18619
+ },
18620
+ {
18621
+ tag: "div",
18622
+ getAttrs: (node) => {
18623
+ const extra = {};
18600
18624
  Array.from(node.attributes).forEach((attr) => {
18601
18625
  extra[attr.name] = attr.value;
18602
18626
  });
18603
18627
  return { extraAttrs: extra };
18604
18628
  }
18605
18629
  },
18630
+ {
18631
+ tag: "blockquote",
18632
+ attrs: { styleId: "BlockQuote" }
18633
+ },
18606
18634
  ...this.options.headingLevels.map((level) => ({
18607
18635
  tag: `h${level}`,
18608
18636
  attrs: { level, styleId: `Heading${level}` }
@@ -18663,11 +18691,6 @@ const Heading = Extension.create({
18663
18691
  name: "heading",
18664
18692
  addOptions() {
18665
18693
  return {
18666
- /**
18667
- * @typedef {Object} HeadingOptions
18668
- * @category Options
18669
- * @property {number[]} [levels=[1,2,3,4,5,6]] - Supported heading levels
18670
- */
18671
18694
  levels: [1, 2, 3, 4, 5, 6]
18672
18695
  };
18673
18696
  },
@@ -18677,10 +18700,8 @@ const Heading = Extension.create({
18677
18700
  * Set a heading with specified level
18678
18701
  * @category Command
18679
18702
  * @param {HeadingAttributes} attributes - Heading attributes including level
18680
- * @returns {Function} Command function
18681
18703
  * @example
18682
- * // Set heading level 2
18683
- * setHeading({ level: 2 })
18704
+ * editor.commands.setHeading({ level: 2 })
18684
18705
  * @note Converts current block to heading
18685
18706
  */
18686
18707
  setHeading: (attributes) => ({ commands: commands2 }) => {
@@ -18692,13 +18713,9 @@ const Heading = Extension.create({
18692
18713
  * Toggle between heading and paragraph
18693
18714
  * @category Command
18694
18715
  * @param {HeadingAttributes} attributes - Heading attributes including level
18695
- * @returns {Function} Command function
18696
18716
  * @example
18697
- * // Toggle heading level 1
18698
- * toggleHeading({ level: 1 })
18699
- *
18700
- * // Toggle heading level 3
18701
- * toggleHeading({ level: 3 })
18717
+ * editor.commands.toggleHeading({ level: 1 })
18718
+ * editor.commands.toggleHeading({ level: 3 })
18702
18719
  * @note Switches between heading and paragraph for the same level
18703
18720
  */
18704
18721
  toggleHeading: (attributes) => ({ commands: commands2 }) => {
@@ -19103,6 +19120,9 @@ const LineBreak = Node$1.create({
19103
19120
  selectable: false,
19104
19121
  content: "",
19105
19122
  atom: true,
19123
+ addOptions() {
19124
+ return {};
19125
+ },
19106
19126
  parseDOM() {
19107
19127
  return [{ tag: "br" }];
19108
19128
  },
@@ -19111,17 +19131,7 @@ const LineBreak = Node$1.create({
19111
19131
  },
19112
19132
  addAttributes() {
19113
19133
  return {
19114
- /**
19115
- * @private
19116
- * @category Attribute
19117
- * @param {string} [lineBreakType] - Type of line break - passthrough in this node
19118
- */
19119
19134
  lineBreakType: { rendered: false },
19120
- /**
19121
- * @private
19122
- * @category Attribute
19123
- * @param {string} [clear] - Clear attribute - passthrough in this node
19124
- */
19125
19135
  clear: { rendered: false }
19126
19136
  };
19127
19137
  },
@@ -19130,9 +19140,8 @@ const LineBreak = Node$1.create({
19130
19140
  /**
19131
19141
  * Insert a line break
19132
19142
  * @category Command
19133
- * @returns {Function} Command function
19134
19143
  * @example
19135
- * insertLineBreak()
19144
+ * editor.commands.insertLineBreak()
19136
19145
  * @note Creates a soft break within the same paragraph
19137
19146
  */
19138
19147
  insertLineBreak: () => ({ commands: commands2 }) => {
@@ -19149,11 +19158,6 @@ const HardBreak = Node$1.create({
19149
19158
  atom: true,
19150
19159
  addOptions() {
19151
19160
  return {
19152
- /**
19153
- * @typedef {Object} HardBreakOptions
19154
- * @category Options
19155
- * @property {Object} [htmlAttributes] - HTML attributes for the break element
19156
- */
19157
19161
  htmlAttributes: {
19158
19162
  contentEditable: "false",
19159
19163
  lineBreakType: "page",
@@ -19164,35 +19168,15 @@ const HardBreak = Node$1.create({
19164
19168
  },
19165
19169
  addAttributes() {
19166
19170
  return {
19167
- /**
19168
- * @private
19169
- * @category Attribute
19170
- * @param {string} [pageBreakSource] - Source of the page break
19171
- */
19172
19171
  pageBreakSource: {
19173
19172
  rendered: false,
19174
19173
  default: null
19175
19174
  },
19176
- /**
19177
- * @private
19178
- * @category Attribute
19179
- * @param {string} [pageBreakType] - Type of page break
19180
- */
19181
19175
  pageBreakType: {
19182
19176
  default: null,
19183
19177
  rendered: false
19184
19178
  },
19185
- /**
19186
- * @private
19187
- * @category Attribute
19188
- * @param {string} [lineBreakType] - Type of line break - passthrough in this node
19189
- */
19190
19179
  lineBreakType: { rendered: false },
19191
- /**
19192
- * @private
19193
- * @category Attribute
19194
- * @param {string} [clear] - Clear attribute - passthrough in this node
19195
- */
19196
19180
  clear: { rendered: false }
19197
19181
  };
19198
19182
  },
@@ -19218,9 +19202,8 @@ const HardBreak = Node$1.create({
19218
19202
  /**
19219
19203
  * Insert a page break
19220
19204
  * @category Command
19221
- * @returns {Function} Command function
19222
19205
  * @example
19223
- * insertPageBreak()
19206
+ * editor.commands.insertPageBreak()
19224
19207
  * @note Forces content to start on a new page when printed
19225
19208
  */
19226
19209
  insertPageBreak: () => ({ commands: commands2 }) => {
@@ -19232,6 +19215,12 @@ const HardBreak = Node$1.create({
19232
19215
  };
19233
19216
  }
19234
19217
  });
19218
+ const getColStyleDeclaration = (minWidth, width) => {
19219
+ if (width) {
19220
+ return ["width", `${Math.max(width, minWidth)}px`];
19221
+ }
19222
+ return ["min-width", `${minWidth}px`];
19223
+ };
19235
19224
  const createTableView = ({ editor }) => {
19236
19225
  return class TableView {
19237
19226
  constructor(node, cellMinWidth) {
@@ -19320,11 +19309,11 @@ function updateTable(editor, node, table) {
19320
19309
  const allExtensionsAttrs = editor.extensionService.attributes;
19321
19310
  const tableExtensionAttrs = allExtensionsAttrs.filter((e) => e.type === "table");
19322
19311
  const htmlAttributes = Attribute.getAttributesToRender(node, tableExtensionAttrs);
19323
- Object.entries(htmlAttributes).forEach(([key, value]) => {
19324
- if (key === "style") {
19312
+ Object.entries(htmlAttributes).forEach(([key2, value]) => {
19313
+ if (key2 === "style") {
19325
19314
  table.style.cssText = value;
19326
19315
  } else {
19327
- table.setAttribute(key, value);
19316
+ table.setAttribute(key2, value);
19328
19317
  }
19329
19318
  });
19330
19319
  }
@@ -19392,26 +19381,55 @@ const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent =
19392
19381
  const tableBorders = createTableBorders();
19393
19382
  return types.table.createChecked({ borders: tableBorders }, rows);
19394
19383
  };
19384
+ const createColGroup = (node, cellMinWidth, overrideCol, overrideValue) => {
19385
+ let totalWidth = 0;
19386
+ let fixedWidth = true;
19387
+ const cols = [];
19388
+ const colsValues = [];
19389
+ const row = node.firstChild;
19390
+ if (!row) return {};
19391
+ for (let i = 0, col = 0; i < row.childCount; i++) {
19392
+ const { colspan, colwidth } = row.child(i).attrs;
19393
+ for (let j = 0; j < colspan; j++, col++) {
19394
+ const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j];
19395
+ totalWidth += hasWidth || cellMinWidth;
19396
+ if (!hasWidth) fixedWidth = false;
19397
+ const [prop, value] = getColStyleDeclaration(cellMinWidth, hasWidth);
19398
+ cols.push(["col", { style: `${prop}: ${value}` }]);
19399
+ colsValues.push(parseInt(value, 10));
19400
+ }
19401
+ }
19402
+ const tableWidth = fixedWidth ? `${totalWidth}px` : "";
19403
+ const tableMinWidth = fixedWidth ? "" : `${totalWidth}px`;
19404
+ const colgroup = ["colgroup", {}, ...cols];
19405
+ const colgroupValues = [...colsValues];
19406
+ return {
19407
+ colgroup,
19408
+ tableWidth,
19409
+ tableMinWidth,
19410
+ colgroupValues
19411
+ };
19412
+ };
19395
19413
  var readFromCache;
19396
19414
  var addToCache;
19397
19415
  if (typeof WeakMap != "undefined") {
19398
19416
  let cache = /* @__PURE__ */ new WeakMap();
19399
- readFromCache = (key) => cache.get(key);
19400
- addToCache = (key, value) => {
19401
- cache.set(key, value);
19417
+ readFromCache = (key2) => cache.get(key2);
19418
+ addToCache = (key2, value) => {
19419
+ cache.set(key2, value);
19402
19420
  return value;
19403
19421
  };
19404
19422
  } else {
19405
19423
  const cache = [];
19406
19424
  const cacheSize = 10;
19407
19425
  let cachePos = 0;
19408
- readFromCache = (key) => {
19426
+ readFromCache = (key2) => {
19409
19427
  for (let i = 0; i < cache.length; i += 2)
19410
- if (cache[i] == key) return cache[i + 1];
19428
+ if (cache[i] == key2) return cache[i + 1];
19411
19429
  };
19412
- addToCache = (key, value) => {
19430
+ addToCache = (key2, value) => {
19413
19431
  if (cachePos == cacheSize) cachePos = 0;
19414
- cache[cachePos++] = key;
19432
+ cache[cachePos++] = key2;
19415
19433
  return cache[cachePos++] = value;
19416
19434
  };
19417
19435
  }
@@ -21575,17 +21593,6 @@ const Table = Node$1.create({
21575
21593
  group: "block",
21576
21594
  isolating: true,
21577
21595
  tableRole: "table",
21578
- /**
21579
- * Table extension options
21580
- * @category Options
21581
- * @typedef {Object} TableOptions
21582
- * @property {Object} [htmlAttributes={'aria-label': 'Table node'}] - Default HTML attributes for all tables
21583
- * @property {boolean} [resizable=true] - Enable column resizing functionality
21584
- * @property {number} [handleWidth=5] - Width of resize handles in pixels
21585
- * @property {number} [cellMinWidth=10] - Minimum cell width constraint in pixels
21586
- * @property {boolean} [lastColumnResizable=true] - Allow resizing of the last column
21587
- * @property {boolean} [allowTableNodeSelection=false] - Enable selecting the entire table node
21588
- */
21589
21596
  addOptions() {
21590
21597
  return {
21591
21598
  htmlAttributes: {
@@ -21645,8 +21652,8 @@ const Table = Node$1.create({
21645
21652
  default: {},
21646
21653
  renderDOM({ borders }) {
21647
21654
  if (!borders) return {};
21648
- const style = Object.entries(borders).reduce((acc, [key, { size, color }]) => {
21649
- return `${acc}border-${key}: ${Math.ceil(size)}px solid ${color || "black"};`;
21655
+ const style = Object.entries(borders).reduce((acc, [key2, { size, color }]) => {
21656
+ return `${acc}border-${key2}: ${Math.ceil(size)}px solid ${color || "black"};`;
21650
21657
  }, "");
21651
21658
  return {
21652
21659
  style
@@ -21705,6 +21712,24 @@ const Table = Node$1.create({
21705
21712
  tableCellSpacing: {
21706
21713
  default: null,
21707
21714
  rendered: false
21715
+ },
21716
+ /**
21717
+ * @category Attribute
21718
+ * @param {TableProperties} [tableProperties] - Properties for the table.
21719
+ * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 371-483
21720
+ */
21721
+ tableProperties: {
21722
+ default: null,
21723
+ rendered: false
21724
+ },
21725
+ /**
21726
+ * @category Attribute
21727
+ * @param {TableGrid} [grid] - Grid definition for the table
21728
+ * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 432
21729
+ */
21730
+ grid: {
21731
+ default: null,
21732
+ rendered: false
21708
21733
  }
21709
21734
  };
21710
21735
  },
@@ -21725,14 +21750,9 @@ const Table = Node$1.create({
21725
21750
  * Insert a new table into the document
21726
21751
  * @category Command
21727
21752
  * @param {TableConfig} [config] - Table configuration options
21728
- * @returns {Function} Command
21729
21753
  * @example
21730
- * // Using default values
21731
- * insertTable() // Creates 3x3 table without header
21732
- *
21733
- * // Using custom values
21734
- * insertTable({ rows: 3, cols: 3, withHeaderRow: true })
21735
- *
21754
+ * editor.commands.insertTable()
21755
+ * editor.commands.insertTable({ rows: 3, cols: 3, withHeaderRow: true })
21736
21756
  */
21737
21757
  insertTable: ({ rows = 3, cols = 3, withHeaderRow = false } = {}) => ({ tr, dispatch, editor }) => {
21738
21758
  const node = createTable(editor.schema, rows, cols, withHeaderRow);
@@ -21745,9 +21765,8 @@ const Table = Node$1.create({
21745
21765
  /**
21746
21766
  * Delete the entire table containing the cursor
21747
21767
  * @category Command
21748
- * @returns {Function} Command
21749
21768
  * @example
21750
- * deleteTable()
21769
+ * editor.commands.deleteTable()
21751
21770
  */
21752
21771
  deleteTable: () => ({ state, dispatch }) => {
21753
21772
  return deleteTable(state, dispatch);
@@ -21755,9 +21774,8 @@ const Table = Node$1.create({
21755
21774
  /**
21756
21775
  * Add a column before the current column
21757
21776
  * @category Command
21758
- * @returns {Function} Command
21759
21777
  * @example
21760
- * addColumnBefore()
21778
+ * editor.commands.addColumnBefore()
21761
21779
  * @note Preserves cell attributes from current column
21762
21780
  */
21763
21781
  addColumnBefore: () => ({ state, dispatch, chain }) => {
@@ -22134,10 +22152,9 @@ const Table = Node$1.create({
22134
22152
  * Set background color for selected cells
22135
22153
  * @category Command
22136
22154
  * @param {string} value - Color value (hex with or without #)
22137
- * @returns {Function} Command
22138
22155
  * @example
22139
- * setCellBackground('#ff0000')
22140
- * setCellBackground('ff0000')
22156
+ * editor.commands.setCellBackground('#ff0000')
22157
+ * editor.commands.setCellBackground('ff0000')
22141
22158
  */
22142
22159
  setCellBackground: (value) => ({ editor, commands: commands2, dispatch }) => {
22143
22160
  const { selection } = editor.state;
@@ -22263,24 +22280,12 @@ const TableHeader = Node$1.create({
22263
22280
  },
22264
22281
  addAttributes() {
22265
22282
  return {
22266
- /**
22267
- * @category Attribute
22268
- * @param {number} [colspan=1] - Number of columns this header spans
22269
- */
22270
22283
  colspan: {
22271
22284
  default: 1
22272
22285
  },
22273
- /**
22274
- * @category Attribute
22275
- * @param {number} [rowspan=1] - Number of rows this header spans
22276
- */
22277
22286
  rowspan: {
22278
22287
  default: 1
22279
22288
  },
22280
- /**
22281
- * @category Attribute
22282
- * @param {number[]} [colwidth] - Column widths array in pixels
22283
- */
22284
22289
  colwidth: {
22285
22290
  default: null,
22286
22291
  parseDOM: (element) => {
@@ -22317,10 +22322,6 @@ const TableRow = Node$1.create({
22317
22322
  },
22318
22323
  addAttributes() {
22319
22324
  return {
22320
- /**
22321
- * @category Attribute
22322
- * @param {number} [rowHeight] - Fixed row height in pixels
22323
- */
22324
22325
  rowHeight: {
22325
22326
  renderDOM({ rowHeight }) {
22326
22327
  if (!rowHeight) return {};
@@ -22328,11 +22329,6 @@ const TableRow = Node$1.create({
22328
22329
  return { style };
22329
22330
  }
22330
22331
  },
22331
- /**
22332
- * Indicates that this row should not be split across pages when paginating/exporting.
22333
- * @category Attribute
22334
- * @param {boolean} [cantSplit]
22335
- */
22336
22332
  cantSplit: {
22337
22333
  default: false,
22338
22334
  parseDOM() {
@@ -22344,44 +22340,30 @@ const TableRow = Node$1.create({
22344
22340
  }
22345
22341
  },
22346
22342
  /**
22347
- * @category Attribute
22348
- * @param {TableRowProperties} [tableRowProperties] - Properties for the table row.
22349
22343
  * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 377-482
22350
22344
  */
22351
22345
  tableRowProperties: { rendered: false },
22352
22346
  /**
22353
- * @category Attribute
22354
- * @param {string} [rsidDel] - Unique identifier used to track the editing session when the row was deleted from the main document.
22355
22347
  * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 472
22356
22348
  */
22357
22349
  rsidDel: { rendered: false },
22358
22350
  /**
22359
- * @category Attribute
22360
- * @param {string} [rsidR] - Unique identifier used to track the editing session when the table row was added to the main document.
22361
22351
  * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 472
22362
22352
  */
22363
22353
  rsidR: { rendered: false },
22364
22354
  /**
22365
- * @category Attribute
22366
- * @param {string} [rsidRPr] - Unique identifier used to track the editing session when the glyph character representing the table row mark was last modified in the main document.
22367
22355
  * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 473
22368
22356
  */
22369
22357
  rsidRPr: { rendered: false },
22370
22358
  /**
22371
- * @category Attribute
22372
- * @param {string} [rsidTr] - Unique identifier used to track the editing session when the table row's properties were last modified in this document.
22373
22359
  * @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 473
22374
22360
  */
22375
22361
  rsidTr: { rendered: false },
22376
22362
  /**
22377
- * @category Attribute
22378
- * @param {string} [paraId] - A randomly generated unique identifier for the table row.
22379
22363
  * @see {@link https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/a0e7d2e2-2246-44c6-96e8-1cf009823615}
22380
22364
  */
22381
22365
  paraId: { rendered: false },
22382
22366
  /**
22383
- * @category Attribute
22384
- * @param {string} [textId] - A randomly generated unique identifier for the text of the table row.
22385
22367
  * @see {@link https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/b7eeddec-7c50-47fb-88b6-1feec3ed832c}
22386
22368
  */
22387
22369
  textId: { rendered: false }
@@ -22408,24 +22390,12 @@ const TableCell = Node$1.create({
22408
22390
  },
22409
22391
  addAttributes() {
22410
22392
  return {
22411
- /**
22412
- * @category Attribute
22413
- * @param {number} [colspan=1] - Number of columns this cell spans
22414
- */
22415
22393
  colspan: {
22416
22394
  default: 1
22417
22395
  },
22418
- /**
22419
- * @category Attribute
22420
- * @param {number} [rowspan=1] - Number of rows this cell spans
22421
- */
22422
22396
  rowspan: {
22423
22397
  default: 1
22424
22398
  },
22425
- /**
22426
- * @category Attribute
22427
- * @param {number[]} [colwidth=[100]] - Column widths array in pixels
22428
- */
22429
22399
  colwidth: {
22430
22400
  default: [100],
22431
22401
  parseDOM: (elem) => {
@@ -22440,10 +22410,6 @@ const TableCell = Node$1.create({
22440
22410
  };
22441
22411
  }
22442
22412
  },
22443
- /**
22444
- * @category Attribute
22445
- * @param {CellBackground} [background] - Cell background color configuration
22446
- */
22447
22413
  background: {
22448
22414
  renderDOM({ background }) {
22449
22415
  if (!background) return {};
@@ -22452,10 +22418,6 @@ const TableCell = Node$1.create({
22452
22418
  return { style };
22453
22419
  }
22454
22420
  },
22455
- /**
22456
- * @category Attribute
22457
- * @param {string} [verticalAlign] - Vertical content alignment (top, middle, bottom)
22458
- */
22459
22421
  verticalAlign: {
22460
22422
  renderDOM({ verticalAlign }) {
22461
22423
  if (!verticalAlign) return {};
@@ -22463,10 +22425,6 @@ const TableCell = Node$1.create({
22463
22425
  return { style };
22464
22426
  }
22465
22427
  },
22466
- /**
22467
- * @category Attribute
22468
- * @param {CellMargins} [cellMargins] - Internal cell padding
22469
- */
22470
22428
  cellMargins: {
22471
22429
  renderDOM({ cellMargins }) {
22472
22430
  if (!cellMargins) return {};
@@ -22479,10 +22437,6 @@ const TableCell = Node$1.create({
22479
22437
  return { style };
22480
22438
  }
22481
22439
  },
22482
- /**
22483
- * @category Attribute
22484
- * @param {CellBorders} [borders] - Cell border configuration
22485
- */
22486
22440
  borders: {
22487
22441
  default: () => createCellBorders(),
22488
22442
  renderDOM({ borders }) {
@@ -22497,20 +22451,10 @@ const TableCell = Node$1.create({
22497
22451
  return { style };
22498
22452
  }
22499
22453
  },
22500
- /**
22501
- * @private
22502
- * @category Attribute
22503
- * @param {string} [widthType='auto'] - Internal width type
22504
- */
22505
22454
  widthType: {
22506
22455
  default: "auto",
22507
22456
  rendered: false
22508
22457
  },
22509
- /**
22510
- * @private
22511
- * @category Attribute
22512
- * @param {string} [widthUnit='px'] - Internal width unit
22513
- */
22514
22458
  widthUnit: {
22515
22459
  default: "px",
22516
22460
  rendered: false
@@ -22761,11 +22705,11 @@ createAnnotation_fn = function({ displayLabel } = {}) {
22761
22705
  let mergedAttrs = Attribute.mergeAttributes(this.htmlAttributes, {
22762
22706
  style: omitHighlight ? "" : annotationStyle
22763
22707
  });
22764
- for (let [key, value] of Object.entries(mergedAttrs)) {
22765
- if (key === "style") {
22708
+ for (let [key2, value] of Object.entries(mergedAttrs)) {
22709
+ if (key2 === "style") {
22766
22710
  annotation.style.cssText = value;
22767
22711
  } else {
22768
- annotation.setAttribute(key, value);
22712
+ annotation.setAttribute(key2, value);
22769
22713
  }
22770
22714
  }
22771
22715
  return {
@@ -22939,13 +22883,13 @@ function hash$2(str) {
22939
22883
  }
22940
22884
  const colorToInt = (x) => parseInt(x.replace(/_/g, ""), 36);
22941
22885
  const compressedColorMap = "1q29ehhb 1n09sgk7 1kl1ekf_ _yl4zsno 16z9eiv3 1p29lhp8 _bd9zg04 17u0____ _iw9zhe5 _to73___ _r45e31e _7l6g016 _jh8ouiv _zn3qba8 1jy4zshs 11u87k0u 1ro9yvyo 1aj3xael 1gz9zjz0 _3w8l4xo 1bf1ekf_ _ke3v___ _4rrkb__ 13j776yz _646mbhl _nrjr4__ _le6mbhl 1n37ehkb _m75f91n _qj3bzfz 1939yygw 11i5z6x8 _1k5f8xs 1509441m 15t5lwgf _ae2th1n _tg1ugcv 1lp1ugcv 16e14up_ _h55rw7n _ny9yavn _7a11xb_ 1ih442g9 _pv442g9 1mv16xof 14e6y7tu 1oo9zkds 17d1cisi _4v9y70f _y98m8kc 1019pq0v 12o9zda8 _348j4f4 1et50i2o _8epa8__ _ts6senj 1o350i2o 1mi9eiuo 1259yrp0 1ln80gnw _632xcoy 1cn9zldc _f29edu4 1n490c8q _9f9ziet 1b94vk74 _m49zkct 1kz6s73a 1eu9dtog _q58s1rz 1dy9sjiq __u89jo3 _aj5nkwg _ld89jo3 13h9z6wx _qa9z2ii _l119xgq _bs5arju 1hj4nwk9 1qt4nwk9 1ge6wau6 14j9zlcw 11p1edc_ _ms1zcxe _439shk6 _jt9y70f _754zsow 1la40eju _oq5p___ _x279qkz 1fa5r3rv _yd2d9ip _424tcku _8y1di2_ _zi2uabw _yy7rn9h 12yz980_ __39ljp6 1b59zg0x _n39zfzp 1fy9zest _b33k___ _hp9wq92 1il50hz4 _io472ub _lj9z3eo 19z9ykg0 _8t8iu3a 12b9bl4a 1ak5yw0o _896v4ku _tb8k8lv _s59zi6t _c09ze0p 1lg80oqn 1id9z8wb _238nba5 1kq6wgdi _154zssg _tn3zk49 _da9y6tc 1sg7cv4f _r12jvtt 1gq5fmkz 1cs9rvci _lp9jn1c _xw1tdnb 13f9zje6 16f6973h _vo7ir40 _bt5arjf _rc45e4t _hr4e100 10v4e100 _hc9zke2 _w91egv_ _sj2r1kk 13c87yx8 _vqpds__ _ni8ggk8 _tj9yqfb 1ia2j4r4 _7x9b10u 1fc9ld4j 1eq9zldr _5j9lhpx _ez9zl6o _md61fzm".split(" ").reduce((acc, next) => {
22942
- const key = colorToInt(next.substring(0, 3));
22886
+ const key2 = colorToInt(next.substring(0, 3));
22943
22887
  const hex = colorToInt(next.substring(3)).toString(16);
22944
22888
  let prefix = "";
22945
22889
  for (let i = 0; i < 6 - hex.length; i++) {
22946
22890
  prefix += "0";
22947
22891
  }
22948
- acc[key] = `${prefix}${hex}`;
22892
+ acc[key2] = `${prefix}${hex}`;
22949
22893
  return acc;
22950
22894
  }, {});
22951
22895
  function nameToHex(color) {
@@ -24061,466 +24005,161 @@ function getFormatAttrsFromMarks(marks) {
24061
24005
  }
24062
24006
  return formatAttrs;
24063
24007
  }
24064
- const ImagePlaceholderPluginKey = new PluginKey("ImagePlaceholder");
24065
- const ImagePlaceholderPlugin = () => {
24066
- return new Plugin({
24067
- key: ImagePlaceholderPluginKey,
24068
- state: {
24069
- init() {
24070
- return DecorationSet.empty;
24071
- },
24072
- apply(tr, set) {
24073
- set = set.map(tr.mapping, tr.doc);
24074
- let action = tr.getMeta(ImagePlaceholderPluginKey);
24075
- if (action?.type === "add") {
24076
- let widget = document.createElement("placeholder");
24077
- let deco = Decoration.widget(action.pos, widget, {
24078
- id: action.id
24079
- });
24080
- set = set.add(tr.doc, [deco]);
24081
- } else if (action?.type === "remove") {
24082
- set = set.remove(set.find(null, null, (spec) => spec.id == action.id));
24083
- }
24084
- return set;
24085
- }
24086
- },
24087
- props: {
24088
- decorations(state) {
24089
- return this.getState(state);
24008
+ const simpleHash = (str) => {
24009
+ let hash2 = 0;
24010
+ for (let i = 0; i < str.length; i++) {
24011
+ const char = str.charCodeAt(i);
24012
+ hash2 = (hash2 << 5) - hash2 + char;
24013
+ hash2 = hash2 & hash2;
24014
+ }
24015
+ return Math.abs(hash2).toString();
24016
+ };
24017
+ const base64ToFile = (base64String) => {
24018
+ const arr = base64String.split(",");
24019
+ const mimeMatch = arr[0].match(/:(.*?);/);
24020
+ const mimeType = mimeMatch ? mimeMatch[1] : "";
24021
+ const data = arr[1];
24022
+ const binaryString = atob(data);
24023
+ const hash2 = simpleHash(binaryString);
24024
+ const extension = mimeType.split("/")[1] || "bin";
24025
+ const filename = `image-${hash2}.${extension}`;
24026
+ const bytes = new Uint8Array(binaryString.length);
24027
+ for (let i = 0; i < binaryString.length; i++) {
24028
+ bytes[i] = binaryString.charCodeAt(i);
24029
+ }
24030
+ const blob = new Blob([bytes], { type: mimeType });
24031
+ return new File([blob], filename, { type: mimeType });
24032
+ };
24033
+ const urlToFile = async (url, filename, mimeType) => {
24034
+ try {
24035
+ const response = await fetch(url, {
24036
+ mode: "cors",
24037
+ credentials: "omit",
24038
+ headers: {
24039
+ // Add common headers that might help with CORS
24040
+ Accept: "image/*,*/*;q=0.8"
24090
24041
  }
24042
+ });
24043
+ if (!response.ok) {
24044
+ console.warn(`Failed to fetch image from ${url}: ${response.status} ${response.statusText}`);
24045
+ return null;
24091
24046
  }
24092
- });
24047
+ const blob = await response.blob();
24048
+ const finalFilename = filename || extractFilenameFromUrl(url);
24049
+ const finalMimeType = mimeType || response.headers.get("content-type") || blob.type || "image/jpeg";
24050
+ return new File([blob], finalFilename, { type: finalMimeType });
24051
+ } catch (error) {
24052
+ if (isCorsError(error)) {
24053
+ console.warn(`CORS policy prevents accessing image from ${url}:`, error.message);
24054
+ return null;
24055
+ }
24056
+ console.error(`Error fetching image from ${url}:`, error);
24057
+ return null;
24058
+ }
24093
24059
  };
24094
- const findPlaceholder = (state, id) => {
24095
- let decos = ImagePlaceholderPluginKey.getState(state);
24096
- let found = decos?.find(null, null, (spec) => spec.id === id);
24097
- return found?.length ? found[0].from : null;
24060
+ const isCorsError = (error) => {
24061
+ const errorMessage = error.message.toLowerCase();
24062
+ const errorName = error.name.toLowerCase();
24063
+ return errorName.includes("cors") || errorMessage.includes("cors") || errorMessage.includes("cross-origin") || errorMessage.includes("access-control") || errorMessage.includes("network error") || // Often indicates CORS in browsers
24064
+ errorMessage.includes("failed to fetch");
24098
24065
  };
24099
- const ImagePositionPluginKey = new PluginKey("ImagePosition");
24100
- const ImagePositionPlugin = ({ editor }) => {
24101
- const { view } = editor;
24102
- let shouldUpdate = false;
24103
- return new Plugin({
24104
- name: "ImagePositionPlugin",
24105
- key: ImagePositionPluginKey,
24106
- state: {
24107
- init() {
24108
- return DecorationSet.empty;
24109
- },
24110
- apply(tr, oldDecorationSet, oldState, newState) {
24111
- if (!tr.docChanged) return oldDecorationSet;
24112
- const decorations = getImagePositionDecorations(newState, view);
24113
- return DecorationSet.create(newState.doc, decorations);
24114
- }
24115
- },
24116
- view: () => {
24117
- return {
24118
- update: (view2, lastState) => {
24119
- const pagination = PaginationPluginKey.getState(lastState);
24120
- if (shouldUpdate) {
24121
- shouldUpdate = false;
24122
- const decorations = getImagePositionDecorations(lastState, view2);
24123
- const updateTransaction = view2.state.tr.setMeta(ImagePositionPluginKey, { decorations });
24124
- view2.dispatch(updateTransaction);
24125
- }
24126
- if (pagination?.isReadyToInit) {
24127
- shouldUpdate = true;
24128
- }
24129
- }
24130
- };
24131
- },
24132
- props: {
24133
- decorations(state) {
24134
- return this.getState(state);
24135
- }
24066
+ const extractFilenameFromUrl = (url) => {
24067
+ try {
24068
+ const urlObj = new URL(url);
24069
+ const pathname = urlObj.pathname;
24070
+ const filename = pathname.split("/").pop();
24071
+ if (filename && !filename.includes(".")) {
24072
+ return `${filename}.jpg`;
24136
24073
  }
24074
+ return filename || "image.jpg";
24075
+ } catch {
24076
+ return "image.jpg";
24077
+ }
24078
+ };
24079
+ const validateUrlAccessibility = async (url) => {
24080
+ try {
24081
+ const response = await fetch(url, {
24082
+ method: "HEAD",
24083
+ mode: "cors",
24084
+ credentials: "omit"
24085
+ });
24086
+ return response.ok;
24087
+ } catch {
24088
+ return false;
24089
+ }
24090
+ };
24091
+ const handleImageUpload = (file) => {
24092
+ return new Promise((resolve, reject) => {
24093
+ let reader = new FileReader();
24094
+ reader.onload = (event) => {
24095
+ resolve(event.target.result);
24096
+ };
24097
+ reader.onerror = reject;
24098
+ setTimeout(() => reader.readAsDataURL(file), 250);
24137
24099
  });
24138
24100
  };
24139
- const getImagePositionDecorations = (state, view) => {
24140
- let decorations = [];
24141
- state.doc.descendants((node, pos) => {
24142
- if (node.attrs.anchorData) {
24143
- let style = "";
24144
- let className = "";
24145
- const { vRelativeFrom, alignH } = node.attrs.anchorData;
24146
- const { size, padding, marginOffset } = node.attrs;
24147
- const pageBreak = findPreviousDomNodeWithClass(view, pos, "pagination-break-wrapper");
24148
- if (pageBreak) {
24149
- switch (alignH) {
24150
- case "left":
24151
- style += "float: left; left: 0; margin-left: 0; ";
24152
- break;
24153
- case "right":
24154
- style += "float: right; right: 0; margin-right: 0; ";
24155
- break;
24156
- case "center":
24157
- style += "display: block; margin-left: auto; margin-right: auto; ";
24158
- break;
24159
- }
24160
- const topPos = marginOffset.top !== void 0 ? marginOffset.top : pageBreak?.offsetTop + pageBreak?.offsetHeight;
24161
- style += vRelativeFrom === "margin" ? `position: absolute; top: ${topPos}px; ` : "";
24162
- if (vRelativeFrom === "margin") {
24163
- const nextPos = view.posAtDOM(pageBreak, 1);
24164
- if (nextPos < 0) {
24165
- const $pos = view.state.doc.resolve(pos);
24166
- decorations.push(
24167
- Decoration.node(pos - 1, pos + $pos.parent.nodeSize - 1, {
24168
- style: `height: ${size.height + parseInt(padding.top) + parseInt(padding.bottom)}px`
24169
- })
24170
- );
24171
- }
24172
- const imageBlock = document.createElement("div");
24173
- imageBlock.className = "anchor-image-placeholder";
24174
- imageBlock.style.float = alignH;
24175
- imageBlock.style.width = size.width + parseInt(padding[alignH]) + "px";
24176
- imageBlock.style.height = size.height + parseInt(padding.top) + parseInt(padding.bottom) + "px";
24177
- decorations.push(Decoration.widget(nextPos, imageBlock, { key: "stable-key" }));
24101
+ const processUploadedImage = (fileData, getMaxContentSize) => {
24102
+ return new Promise((resolve, reject) => {
24103
+ const img = new window.Image();
24104
+ img.onload = () => {
24105
+ const canvas = document.createElement("canvas");
24106
+ const { width: logicalWidth, height: logicalHeight } = getAllowedImageDimensions(
24107
+ img.width,
24108
+ img.height,
24109
+ getMaxContentSize
24110
+ );
24111
+ canvas.width = img.width;
24112
+ canvas.height = img.height;
24113
+ const ctx = canvas.getContext("2d");
24114
+ if (ctx) {
24115
+ ctx.imageSmoothingEnabled = true;
24116
+ try {
24117
+ ctx.imageSmoothingQuality = "high";
24118
+ } catch {
24178
24119
  }
24179
24120
  }
24180
- decorations.push(Decoration.inline(pos, pos + node.nodeSize, { style, class: className }));
24181
- }
24121
+ ctx.drawImage(img, 0, 0, img.width, img.height);
24122
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio ? window.devicePixelRatio : 1;
24123
+ const targetPixelWidth = Math.round(logicalWidth * dpr);
24124
+ const targetPixelHeight = Math.round(logicalHeight * dpr);
24125
+ const finalTargetWidth = Math.min(targetPixelWidth, img.width);
24126
+ const finalTargetHeight = Math.min(targetPixelHeight, img.height);
24127
+ const resizeNeeded = finalTargetWidth !== img.width || finalTargetHeight !== img.height;
24128
+ if (resizeNeeded) {
24129
+ multiStepResize(canvas, finalTargetWidth, finalTargetHeight);
24130
+ }
24131
+ if (typeof fileData === "string") {
24132
+ const resizedBase64 = canvas.toDataURL();
24133
+ resolve(resizedBase64);
24134
+ } else {
24135
+ canvas.toBlob((blob) => {
24136
+ const updatedFile = new File([blob], fileData.name, {
24137
+ type: fileData.type,
24138
+ lastModified: Date.now()
24139
+ });
24140
+ resolve({ file: updatedFile, width: logicalWidth, height: logicalHeight });
24141
+ });
24142
+ }
24143
+ };
24144
+ img.onerror = (error) => reject(error);
24145
+ img.src = typeof fileData === "string" ? fileData : URL.createObjectURL(fileData);
24182
24146
  });
24183
- return decorations;
24184
24147
  };
24185
- const findPreviousDomNodeWithClass = (view, pos, className) => {
24186
- let { node } = view.domAtPos(pos);
24187
- if (node.nodeType === 3) {
24188
- node = node.parentNode;
24148
+ const getAllowedImageDimensions = (width, height, getMaxContentSize) => {
24149
+ const { width: maxWidth, height: maxHeight } = getMaxContentSize();
24150
+ if (!maxWidth || !maxHeight) return { width, height };
24151
+ let adjustedWidth = width;
24152
+ let adjustedHeight = height;
24153
+ const aspectRatio = width / height;
24154
+ if (height > maxHeight) {
24155
+ adjustedHeight = maxHeight;
24156
+ adjustedWidth = Math.round(maxHeight * aspectRatio);
24189
24157
  }
24190
- while (node) {
24191
- if (node.classList && node.classList.contains(className)) {
24192
- return node;
24193
- }
24194
- if (node.previousSibling) {
24195
- node = node.previousSibling;
24196
- while (node && node.lastChild) {
24197
- node = node.lastChild;
24198
- }
24199
- } else {
24200
- node = node.parentNode;
24201
- }
24158
+ if (adjustedWidth > maxWidth) {
24159
+ adjustedWidth = maxWidth;
24160
+ adjustedHeight = Math.round(maxWidth / aspectRatio);
24202
24161
  }
24203
- return null;
24204
- };
24205
- const Image = Node$1.create({
24206
- name: "image",
24207
- group: "inline",
24208
- inline: true,
24209
- draggable: true,
24210
- addOptions() {
24211
- return {
24212
- allowBase64: true,
24213
- htmlAttributes: {
24214
- style: "display: inline-block;",
24215
- "aria-label": "Image node"
24216
- }
24217
- };
24218
- },
24219
- addStorage() {
24220
- return {
24221
- media: {}
24222
- };
24223
- },
24224
- addAttributes() {
24225
- return {
24226
- /**
24227
- * @category Attribute
24228
- * @param {string} [src] - Image source URL or path
24229
- */
24230
- src: {
24231
- default: null,
24232
- renderDOM: ({ src }) => {
24233
- return {
24234
- src: this.storage.media[src] ?? src
24235
- };
24236
- }
24237
- },
24238
- /**
24239
- * @category Attribute
24240
- * @param {string} [alt='Uploaded picture'] - Alternative text for accessibility
24241
- */
24242
- alt: {
24243
- default: "Uploaded picture"
24244
- },
24245
- /**
24246
- * @category Attribute
24247
- * @param {string} [id] - Image element ID
24248
- * @private
24249
- */
24250
- id: { rendered: false },
24251
- /**
24252
- * @category Attribute
24253
- * @param {string} [title] - Image title/tooltip text
24254
- */
24255
- title: {
24256
- default: null
24257
- },
24258
- /**
24259
- * @category Attribute
24260
- * @param {string} [rId] - Relationship ID for Word export
24261
- * @private
24262
- */
24263
- rId: {
24264
- default: null,
24265
- rendered: false
24266
- },
24267
- /**
24268
- * @category Attribute
24269
- * @param {Object} [originalPadding] - Original padding values from Word import
24270
- * @private
24271
- */
24272
- originalPadding: {
24273
- default: null,
24274
- rendered: false
24275
- },
24276
- /**
24277
- * @category Attribute
24278
- * @param {Object} [originalAttributes] - Original attributes from Word import
24279
- * @private
24280
- */
24281
- originalAttributes: { rendered: false },
24282
- /**
24283
- * @category Attribute
24284
- * @param {boolean} [wrapTopAndBottom] - Wrap text above and below image
24285
- * @private
24286
- */
24287
- wrapTopAndBottom: { rendered: false },
24288
- /**
24289
- * @category Attribute
24290
- * @param {Object} [anchorData] - Anchor positioning data for Word
24291
- * @private
24292
- */
24293
- anchorData: {
24294
- default: null,
24295
- rendered: false
24296
- },
24297
- /**
24298
- * @category Attribute
24299
- * @param {boolean} [isAnchor] - Whether image is anchored
24300
- * @private
24301
- */
24302
- isAnchor: { rendered: false },
24303
- /**
24304
- * @category Attribute
24305
- * @param {boolean} [simplePos] - Simple positioning flag
24306
- * @private
24307
- */
24308
- simplePos: { rendered: false },
24309
- /**
24310
- * @category Attribute
24311
- * @param {string} [wrapText] - Text wrapping style
24312
- * @private
24313
- */
24314
- wrapText: { rendered: false },
24315
- extension: { rendered: false },
24316
- /**
24317
- * @category Attribute
24318
- * @param {Object} [size] - Image dimensions
24319
- * @param {number} [size.width] - Width in pixels
24320
- * @param {number} [size.height] - Height in pixels
24321
- */
24322
- size: {
24323
- default: {},
24324
- renderDOM: ({ size, extension }) => {
24325
- let style = "";
24326
- const { width, height } = size ?? {};
24327
- if (width) style += `width: ${width}px;`;
24328
- if (height && ["emf", "wmf"].includes(extension))
24329
- style += `height: ${height}px; border: 1px solid black; position: absolute;`;
24330
- else if (height) style += "height: auto;";
24331
- return { style };
24332
- }
24333
- },
24334
- /**
24335
- * @category Attribute
24336
- * @param {Object} [padding] - Image padding/margins
24337
- * @param {number} [padding.left] - Left padding in pixels
24338
- * @param {number} [padding.top] - Top padding in pixels
24339
- * @param {number} [padding.bottom] - Bottom padding in pixels
24340
- * @param {number} [padding.right] - Right padding in pixels
24341
- */
24342
- padding: {
24343
- default: {},
24344
- renderDOM: ({ padding, marginOffset }) => {
24345
- const { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
24346
- let style = "";
24347
- if (left2 && !marginOffset?.left) style += `margin-left: ${left2}px;`;
24348
- if (top2 && !marginOffset?.top) style += `margin-top: ${top2}px;`;
24349
- if (bottom2) style += `margin-bottom: ${bottom2}px;`;
24350
- if (right2) style += `margin-right: ${right2}px;`;
24351
- return { style };
24352
- }
24353
- },
24354
- /**
24355
- * @category Attribute
24356
- * @param {Object} [marginOffset] - Margin offset for anchored images
24357
- * @param {number} [marginOffset.left] - Left margin offset
24358
- * @param {number} [marginOffset.top] - Top margin offset
24359
- */
24360
- marginOffset: {
24361
- default: {},
24362
- renderDOM: ({ marginOffset, anchorData }) => {
24363
- const relativeFromPageV = anchorData?.vRelativeFrom === "page";
24364
- const maxMarginV = 500;
24365
- const { left: left2 = 0, top: top2 = 0 } = marginOffset ?? {};
24366
- let style = "";
24367
- if (left2) style += `margin-left: ${left2}px;`;
24368
- if (top2) {
24369
- if (relativeFromPageV && top2 >= maxMarginV) style += `margin-top: ${maxMarginV}px;`;
24370
- else style += `margin-top: ${top2}px;`;
24371
- }
24372
- return { style };
24373
- }
24374
- },
24375
- /**
24376
- * @category Attribute
24377
- * @param {string} [style] - Custom inline CSS styles
24378
- */
24379
- style: {
24380
- default: null,
24381
- rendered: true,
24382
- renderDOM: ({ style }) => {
24383
- if (!style) return {};
24384
- return { style };
24385
- }
24386
- }
24387
- };
24388
- },
24389
- parseDOM() {
24390
- return [
24391
- {
24392
- tag: this.options.allowBase64 ? "img[src]" : 'img[src]:not([src^="data:"])'
24393
- }
24394
- ];
24395
- },
24396
- renderDOM({ htmlAttributes }) {
24397
- return ["img", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
24398
- },
24399
- addCommands() {
24400
- return {
24401
- /**
24402
- * Insert an image at the current position
24403
- * @category Command
24404
- * @param {Object} options - Image attributes
24405
- * @param {string} options.src - Image source URL or data URI
24406
- * @param {string} [options.alt] - Alternative text
24407
- * @param {string} [options.title] - Image title
24408
- * @param {Object} [options.size] - Image dimensions
24409
- * @returns {Function} Command function
24410
- * @example
24411
- * // Insert an image from a URL
24412
- * setImage({ src: 'https://example.com/image.jpg' })
24413
- *
24414
- * // Insert a base64 encoded image
24415
- * setImage({
24416
- * src: 'data:image/png;base64,...',
24417
- * alt: 'Company logo',
24418
- * size: { width: 200 }
24419
- * })
24420
- * @note Supports URLs, relative paths, and base64 data URIs
24421
- */
24422
- setImage: (options) => ({ commands: commands2 }) => {
24423
- return commands2.insertContent({
24424
- type: this.name,
24425
- attrs: options
24426
- });
24427
- }
24428
- };
24429
- },
24430
- addPmPlugins() {
24431
- return [ImagePlaceholderPlugin(), ImagePositionPlugin({ editor: this.editor })];
24432
- }
24433
- });
24434
- const ACCEPT_IMAGE_TYPES = [".jpg", ".jpeg", ".png", "image/jpeg", "image/png"];
24435
- const getFileOpener = () => {
24436
- let fileInput = document.createElement("input");
24437
- fileInput.type = "file";
24438
- let acceptTypes = ACCEPT_IMAGE_TYPES;
24439
- fileInput.accept = acceptTypes.join(",");
24440
- const openFile = () => {
24441
- return new Promise((resolve, reject) => {
24442
- fileInput.onchange = async () => {
24443
- const files = fileInput.files;
24444
- if (!files) return resolve(null);
24445
- const file = files.item(0);
24446
- if (!file) return resolve(null);
24447
- return resolve({ file });
24448
- };
24449
- fileInput.oncancel = () => resolve(null);
24450
- fileInput.onerror = reject;
24451
- fileInput.click();
24452
- });
24453
- };
24454
- return openFile;
24455
- };
24456
- const handleImageUpload = (file) => {
24457
- return new Promise((resolve, reject) => {
24458
- let reader = new FileReader();
24459
- reader.onload = (event) => {
24460
- resolve(event.target.result);
24461
- };
24462
- reader.onerror = reject;
24463
- setTimeout(() => reader.readAsDataURL(file), 250);
24464
- });
24465
- };
24466
- const processUploadedImage = (fileData, editor) => {
24467
- return new Promise((resolve, reject) => {
24468
- const img = new window.Image();
24469
- img.onload = () => {
24470
- const canvas = document.createElement("canvas");
24471
- const { width: logicalWidth, height: logicalHeight } = getAllowedImageDimensions(img.width, img.height, editor);
24472
- canvas.width = img.width;
24473
- canvas.height = img.height;
24474
- const ctx = canvas.getContext("2d");
24475
- if (ctx) {
24476
- ctx.imageSmoothingEnabled = true;
24477
- try {
24478
- ctx.imageSmoothingQuality = "high";
24479
- } catch {
24480
- }
24481
- }
24482
- ctx.drawImage(img, 0, 0, img.width, img.height);
24483
- const dpr = typeof window !== "undefined" && window.devicePixelRatio ? window.devicePixelRatio : 1;
24484
- const targetPixelWidth = Math.round(logicalWidth * dpr);
24485
- const targetPixelHeight = Math.round(logicalHeight * dpr);
24486
- const finalTargetWidth = Math.min(targetPixelWidth, img.width);
24487
- const finalTargetHeight = Math.min(targetPixelHeight, img.height);
24488
- const resizeNeeded = finalTargetWidth !== img.width || finalTargetHeight !== img.height;
24489
- if (resizeNeeded) {
24490
- multiStepResize(canvas, finalTargetWidth, finalTargetHeight);
24491
- }
24492
- if (typeof fileData === "string") {
24493
- const resizedBase64 = canvas.toDataURL();
24494
- resolve(resizedBase64);
24495
- } else {
24496
- canvas.toBlob((blob) => {
24497
- const updatedFile = new File([blob], fileData.name, {
24498
- type: fileData.type,
24499
- lastModified: Date.now()
24500
- });
24501
- resolve({ file: updatedFile, width: logicalWidth, height: logicalHeight });
24502
- });
24503
- }
24504
- };
24505
- img.onerror = (error) => reject(error);
24506
- img.src = typeof fileData === "string" ? fileData : URL.createObjectURL(fileData);
24507
- });
24508
- };
24509
- const getAllowedImageDimensions = (width, height, editor) => {
24510
- const { width: maxWidth, height: maxHeight } = editor.getMaxContentSize();
24511
- if (!maxWidth || !maxHeight) return { width, height };
24512
- let adjustedWidth = width;
24513
- let adjustedHeight = height;
24514
- const aspectRatio = width / height;
24515
- if (height > maxHeight) {
24516
- adjustedHeight = maxHeight;
24517
- adjustedWidth = Math.round(maxHeight * aspectRatio);
24518
- }
24519
- if (adjustedWidth > maxWidth) {
24520
- adjustedWidth = maxWidth;
24521
- adjustedHeight = Math.round(maxWidth / aspectRatio);
24522
- }
24523
- return { width: adjustedWidth, height: adjustedHeight };
24162
+ return { width: adjustedWidth, height: adjustedHeight };
24524
24163
  };
24525
24164
  function resample_high_quality(canvas, width, height, resize_canvas) {
24526
24165
  var width_source = canvas.width;
@@ -24584,114 +24223,679 @@ function resample_high_quality(canvas, width, height, resize_canvas) {
24584
24223
  }
24585
24224
  ctx.putImageData(img2, 0, 0);
24586
24225
  }
24587
- function multiStepResize(canvas, targetWidth, targetHeight) {
24588
- const originalWidth = canvas.width;
24589
- const originalHeight = canvas.height;
24590
- const scaleX = targetWidth / originalWidth;
24591
- const scaleY = targetHeight / originalHeight;
24592
- const scaleFactor = Math.min(scaleX, scaleY);
24593
- if (scaleFactor < 0.5) {
24594
- let currentWidth = originalWidth;
24595
- let currentHeight = originalHeight;
24596
- while (currentWidth > targetWidth * 2 || currentHeight > targetHeight * 2) {
24597
- const nextWidth = Math.round(currentWidth / 2);
24598
- const nextHeight = Math.round(currentHeight / 2);
24599
- resample_high_quality(canvas, nextWidth, nextHeight);
24600
- currentWidth = nextWidth;
24601
- currentHeight = nextHeight;
24602
- }
24603
- if (currentWidth !== targetWidth || currentHeight !== targetHeight) {
24604
- resample_high_quality(canvas, targetWidth, targetHeight);
24605
- }
24606
- } else {
24607
- resample_high_quality(canvas, targetWidth, targetHeight);
24226
+ function multiStepResize(canvas, width, height) {
24227
+ let oc = document.createElement("canvas");
24228
+ let octx = oc.getContext("2d");
24229
+ let ctx = canvas.getContext("2d");
24230
+ let steps = Math.ceil(Math.log(canvas.width / width) / Math.log(2));
24231
+ steps = Math.max(steps, 1);
24232
+ let stepWidth = width * Math.pow(2, steps - 1);
24233
+ let stepHeight = height * Math.pow(2, steps - 1);
24234
+ let currentWidth = canvas.width;
24235
+ let currentHeight = canvas.height;
24236
+ oc.width = currentWidth;
24237
+ oc.height = currentHeight;
24238
+ octx.drawImage(canvas, 0, 0);
24239
+ while (steps > 0) {
24240
+ stepWidth = Math.max(stepWidth, width);
24241
+ stepHeight = Math.max(stepHeight, height);
24242
+ canvas.width = stepWidth;
24243
+ canvas.height = stepHeight;
24244
+ ctx.drawImage(oc, 0, 0, currentWidth, currentHeight, 0, 0, stepWidth, stepHeight);
24245
+ currentWidth = stepWidth;
24246
+ currentHeight = stepHeight;
24247
+ oc.width = currentWidth;
24248
+ oc.height = currentHeight;
24249
+ octx.drawImage(canvas, 0, 0);
24250
+ stepWidth = Math.round(stepWidth / 2);
24251
+ stepHeight = Math.round(stepHeight / 2);
24252
+ steps--;
24253
+ }
24254
+ resample_high_quality(canvas, width, height);
24255
+ }
24256
+ const FALLBACK_NAME = "image";
24257
+ const stripDiacritics = (value) => value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
24258
+ const sanitizeSegment = (segment, { allowDots = false } = {}) => {
24259
+ if (!segment) return "";
24260
+ const normalized = stripDiacritics(segment).replace(/[\s\u2000-\u206f]+/g, "_").replace(/[\\/]+/g, "_");
24261
+ const allowedPattern = allowDots ? /[^0-9A-Za-z._-]+/g : /[^0-9A-Za-z_-]+/g;
24262
+ let sanitized = normalized.replace(allowedPattern, "_");
24263
+ sanitized = sanitized.replace(/_+/g, "_");
24264
+ sanitized = sanitized.replace(/^[_.-]+/, "");
24265
+ sanitized = sanitized.replace(/[_-]+$/, "");
24266
+ return sanitized;
24267
+ };
24268
+ const splitFileName = (name) => {
24269
+ const trimmed = name?.trim?.() ?? "";
24270
+ const lastDot = trimmed.lastIndexOf(".");
24271
+ if (lastDot <= 0 || lastDot === trimmed.length - 1) {
24272
+ return { base: trimmed, ext: "" };
24608
24273
  }
24609
- }
24610
- const startImageUpload = async ({ editor, view, file }) => {
24611
- const imageUploadHandler = typeof editor.options.handleImageUpload === "function" ? editor.options.handleImageUpload : handleImageUpload;
24274
+ return {
24275
+ base: trimmed.slice(0, lastDot),
24276
+ ext: trimmed.slice(lastDot + 1)
24277
+ };
24278
+ };
24279
+ const sanitizeImageFileName = (inputName) => {
24280
+ const { base: base2, ext } = splitFileName(inputName || "");
24281
+ const sanitizedBase = sanitizeSegment(base2, { allowDots: true }) || FALLBACK_NAME;
24282
+ const sanitizedExt = sanitizeSegment(ext, { allowDots: false }).toLowerCase();
24283
+ if (!sanitizedExt) return sanitizedBase;
24284
+ return `${sanitizedBase}.${sanitizedExt}`;
24285
+ };
24286
+ const ensureUniqueFileName = (preferredName, existingNames = /* @__PURE__ */ new Set()) => {
24287
+ const sanitized = sanitizeImageFileName(preferredName);
24288
+ if (!existingNames || typeof existingNames.has !== "function") {
24289
+ return sanitized;
24290
+ }
24291
+ const existingSet = /* @__PURE__ */ new Set();
24292
+ existingNames.forEach((name) => existingSet.add(sanitizeImageFileName(name)));
24293
+ if (!existingSet.has(sanitized)) {
24294
+ return sanitized;
24295
+ }
24296
+ const { base: base2, ext } = splitFileName(sanitized);
24297
+ let counter = 1;
24298
+ let candidate = sanitized;
24299
+ const suffix = () => `${base2}-${counter}${ext ? `.${ext}` : ""}`;
24300
+ while (existingSet.has(candidate)) {
24301
+ candidate = suffix();
24302
+ counter += 1;
24303
+ }
24304
+ return candidate;
24305
+ };
24306
+ const buildMediaPath = (fileName) => `word/media/${fileName}`;
24307
+ const fileTooLarge = (file) => {
24612
24308
  let fileSizeMb = Number((file.size / (1024 * 1024)).toFixed(4));
24613
24309
  if (fileSizeMb > 5) {
24614
24310
  window.alert("Image size must be less than 5MB");
24615
- return;
24311
+ return true;
24312
+ }
24313
+ return false;
24314
+ };
24315
+ const checkAndProcessImage = async ({ getMaxContentSize, file }) => {
24316
+ if (fileTooLarge(file)) {
24317
+ return { file: null, size: { width: 0, height: 0 } };
24616
24318
  }
24617
- let width;
24618
- let height;
24619
24319
  try {
24620
- const processedImageResult = await processUploadedImage(file, editor);
24621
- width = processedImageResult.width;
24622
- height = processedImageResult.height;
24623
- file = processedImageResult.file;
24320
+ const processedImageResult = await processUploadedImage(file, getMaxContentSize);
24321
+ const process = processedImageResult;
24322
+ return { file: process.file, size: { width: process.width, height: process.height } };
24624
24323
  } catch (err) {
24625
24324
  console.warn("Error processing image:", err);
24626
- return;
24325
+ return { file: null, size: { width: 0, height: 0 } };
24627
24326
  }
24628
- await uploadImage({
24629
- editor,
24630
- view,
24631
- file,
24632
- size: { width, height },
24633
- uploadHandler: imageUploadHandler
24634
- });
24635
24327
  };
24636
- async function uploadImage({ editor, view, file, size, uploadHandler }) {
24637
- let id = {};
24638
- let { tr, schema } = view.state;
24328
+ function replaceSelectionWithImagePlaceholder({ editorOptions, view, id }) {
24329
+ let { tr } = view.state;
24639
24330
  let { selection } = tr;
24640
- if (editor.options.isHeaderOrFooter) {
24641
- selection = editor.options.lastSelection;
24331
+ if (editorOptions.isHeaderOrFooter) {
24332
+ selection = editorOptions.lastSelection;
24642
24333
  }
24643
- if (!selection.empty && !editor.options.isHeaderOrFooter) {
24334
+ if (!selection.empty && !editorOptions.isHeaderOrFooter) {
24644
24335
  tr.deleteSelection();
24645
24336
  }
24646
- let imageMeta = {
24647
- type: "add",
24648
- pos: selection.from,
24649
- id
24650
- };
24651
- tr.setMeta(ImagePlaceholderPluginKey, imageMeta);
24337
+ tr = addImagePlaceholder(view.state, tr, id, selection.from);
24652
24338
  view.dispatch(tr);
24339
+ }
24340
+ const generateUniqueDocPrId = (editor) => {
24341
+ const existingIds = /* @__PURE__ */ new Set();
24342
+ editor?.state?.doc?.descendants((node) => {
24343
+ if (node.type.name === "image" && node.attrs.id !== void 0 && node.attrs.id !== null) {
24344
+ existingIds.add(String(node.attrs.id));
24345
+ }
24346
+ });
24347
+ let candidate;
24348
+ do {
24349
+ const hex = generateDocxRandomId();
24350
+ candidate = String(parseInt(hex, 16));
24351
+ } while (!candidate || existingIds.has(candidate));
24352
+ return candidate;
24353
+ };
24354
+ async function uploadAndInsertImage({ editor, view, file, size, id }) {
24355
+ const imageUploadHandler = typeof editor.options.handleImageUpload === "function" ? editor.options.handleImageUpload : handleImageUpload;
24356
+ const placeholderId = id;
24653
24357
  try {
24654
- let url = await uploadHandler(file);
24655
- let fileName = file.name.replace(" ", "_");
24656
- let placeholderPos = findPlaceholder(view.state, id);
24358
+ const existingFileNames = new Set(Object.keys(editor.storage.image.media ?? {}).map((key2) => key2.split("/").pop()));
24359
+ const uniqueFileName = ensureUniqueFileName(file.name, existingFileNames);
24360
+ const normalizedFile = uniqueFileName === file.name ? file : new File([file], uniqueFileName, {
24361
+ type: file.type,
24362
+ lastModified: file.lastModified ?? Date.now()
24363
+ });
24364
+ let url = await imageUploadHandler(normalizedFile);
24365
+ let placeholderPos = findPlaceholder(view.state, placeholderId);
24657
24366
  if (placeholderPos == null) {
24658
24367
  return;
24659
24368
  }
24660
- let removeMeta = { type: "remove", id };
24661
- let mediaPath = `word/media/${fileName}`;
24369
+ const mediaPath = buildMediaPath(uniqueFileName);
24370
+ const docPrId = generateUniqueDocPrId(editor);
24662
24371
  let rId = null;
24663
24372
  if (editor.options.mode === "docx") {
24664
24373
  const [, path] = mediaPath.split("word/");
24665
- const imageid = addImageRelationship({ editor, path });
24666
- if (imageid) rId = imageid;
24374
+ const id2 = addImageRelationship({ editor, path });
24375
+ if (id2) rId = id2;
24667
24376
  }
24668
- let imageNode = schema.nodes.image.create({
24377
+ let imageNode = view.state.schema.nodes.image.create({
24669
24378
  src: mediaPath,
24670
24379
  size,
24380
+ id: docPrId,
24671
24381
  rId
24672
24382
  });
24673
24383
  editor.storage.image.media = Object.assign(editor.storage.image.media, { [mediaPath]: url });
24674
- if (editor.options.ydoc) {
24384
+ if (editor.options.ydoc && typeof editor.commands.addImageToCollaboration === "function") {
24675
24385
  editor.commands.addImageToCollaboration({ mediaPath, fileData: url });
24676
24386
  }
24677
- view.dispatch(
24678
- view.state.tr.replaceWith(placeholderPos, placeholderPos, imageNode).setMeta(ImagePlaceholderPluginKey, removeMeta)
24679
- );
24387
+ let tr = view.state.tr;
24388
+ tr.replaceWith(placeholderPos, placeholderPos, imageNode);
24389
+ tr = removeImagePlaceholder(view.state, tr, placeholderId);
24390
+ view.dispatch(tr);
24680
24391
  } catch {
24681
- let removeMeta = { type: "remove", id };
24682
- view.dispatch(tr.setMeta(ImagePlaceholderPluginKey, removeMeta));
24392
+ const tr = removeImagePlaceholder(view.state, view.state.tr, placeholderId);
24393
+ view.dispatch(tr);
24683
24394
  }
24684
24395
  }
24685
24396
  function addImageRelationship({ editor, path }) {
24686
24397
  const target = path;
24687
24398
  const type = "image";
24688
24399
  try {
24689
- const relationshipId = insertNewRelationship(target, type, editor);
24690
- return relationshipId;
24400
+ const id = insertNewRelationship(target, type, editor);
24401
+ return id;
24691
24402
  } catch {
24692
24403
  return null;
24693
24404
  }
24694
24405
  }
24406
+ const key = new PluginKey("ImageRegistration");
24407
+ const ImageRegistrationPlugin = ({ editor }) => {
24408
+ const { view } = editor;
24409
+ return new Plugin({
24410
+ key,
24411
+ state: {
24412
+ init() {
24413
+ return { set: DecorationSet.empty };
24414
+ },
24415
+ apply(tr, { set }) {
24416
+ const meta = tr.getMeta(key);
24417
+ if (meta) {
24418
+ set = meta.set;
24419
+ return { set };
24420
+ }
24421
+ set = set.map(tr.mapping, tr.doc);
24422
+ return { set };
24423
+ }
24424
+ },
24425
+ appendTransaction: (trs, _oldState, state) => {
24426
+ let foundImages = [];
24427
+ trs.forEach((tr2) => {
24428
+ if (tr2.docChanged) {
24429
+ tr2.steps.forEach((step, index2) => {
24430
+ const stepMap = step.getMap();
24431
+ foundImages = foundImages.map(({ node, pos, id }) => {
24432
+ const mappedPos = stepMap.map(pos, -1);
24433
+ return { node, pos: mappedPos, id };
24434
+ });
24435
+ if (step instanceof ReplaceStep || step instanceof ReplaceAroundStep$1) {
24436
+ (tr2.docs[index2 + 1] || tr2.doc).nodesBetween(
24437
+ stepMap.map(step.from, -1),
24438
+ stepMap.map(step.to, 1),
24439
+ (node, pos) => {
24440
+ if (node.type.name === "image" && !node.attrs.src.startsWith("word/media")) {
24441
+ const id = {};
24442
+ foundImages.push({ node, pos, id });
24443
+ } else {
24444
+ return true;
24445
+ }
24446
+ }
24447
+ );
24448
+ }
24449
+ });
24450
+ }
24451
+ });
24452
+ if (!foundImages || foundImages.length === 0) {
24453
+ return null;
24454
+ }
24455
+ registerImages(foundImages, editor, view);
24456
+ const tr = state.tr;
24457
+ let { set } = key.getState(state);
24458
+ foundImages.slice().sort((a, b) => a.pos - b.pos).forEach(({ pos, id }) => {
24459
+ let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
24460
+ side: -1,
24461
+ id
24462
+ });
24463
+ set = set.add(tr.doc, [deco]);
24464
+ });
24465
+ foundImages.slice().sort((a, b) => b.pos - a.pos).forEach(({ node, pos }) => {
24466
+ tr.delete(pos, pos + node.nodeSize);
24467
+ });
24468
+ set = set.map(tr.mapping, tr.doc);
24469
+ tr.setMeta(key, { set });
24470
+ return tr;
24471
+ },
24472
+ props: {
24473
+ decorations(state) {
24474
+ let { set } = key.getState(state);
24475
+ return set;
24476
+ }
24477
+ }
24478
+ });
24479
+ };
24480
+ const findPlaceholder = (state, id) => {
24481
+ let { set } = key.getState(state);
24482
+ let found = set?.find(null, null, (spec) => spec.id === id);
24483
+ return found?.length ? found[0].from : null;
24484
+ };
24485
+ const removeImagePlaceholder = (state, tr, id) => {
24486
+ let { set } = key.getState(state);
24487
+ set = set.map(tr.mapping, tr.doc);
24488
+ set = set.remove(set.find(null, null, (spec) => spec.id == id));
24489
+ return tr.setMeta(key, { set, type: "remove" });
24490
+ };
24491
+ const addImagePlaceholder = (state, tr, id, pos) => {
24492
+ let { set } = key.getState(state);
24493
+ set = set.map(tr.mapping, tr.doc);
24494
+ let deco = Decoration.widget(pos, () => document.createElement("placeholder"), {
24495
+ id
24496
+ });
24497
+ set = set.add(tr.doc, [deco]);
24498
+ return tr.setMeta(key, { set, type: "add" });
24499
+ };
24500
+ const getImageRegistrationMetaType = (tr) => {
24501
+ const meta = tr.getMeta(key);
24502
+ if (meta && meta.type) {
24503
+ return meta.type;
24504
+ }
24505
+ return null;
24506
+ };
24507
+ const registerImages = async (foundImages, editor, view) => {
24508
+ foundImages.forEach(async (image) => {
24509
+ const src = image.node.attrs.src;
24510
+ const id = image.id;
24511
+ let file = null;
24512
+ if (src.startsWith("http")) {
24513
+ const isAccessible = await validateUrlAccessibility(src);
24514
+ if (isAccessible) {
24515
+ file = await urlToFile(src);
24516
+ } else {
24517
+ console.warn(`Image URL ${src} is not accessible due to CORS or other restrictions. Using original URL.`);
24518
+ const tr = view.state.tr;
24519
+ removeImagePlaceholder(view.state, tr, id);
24520
+ view.dispatch(tr);
24521
+ return;
24522
+ }
24523
+ } else if (src.startsWith("data:")) {
24524
+ file = base64ToFile(src);
24525
+ } else {
24526
+ console.error(`Unsupported image source: ${src}`);
24527
+ }
24528
+ if (!file) {
24529
+ const tr = view.state.tr;
24530
+ removeImagePlaceholder(view.state, tr, id);
24531
+ view.dispatch(tr);
24532
+ return;
24533
+ }
24534
+ try {
24535
+ const process = await checkAndProcessImage({
24536
+ getMaxContentSize: () => editor.getMaxContentSize(),
24537
+ file
24538
+ });
24539
+ if (!process.file) {
24540
+ const tr = view.state.tr;
24541
+ removeImagePlaceholder(view.state, tr, id);
24542
+ view.dispatch(tr);
24543
+ return;
24544
+ }
24545
+ await uploadAndInsertImage({ editor, view, file: process.file, size: process.size, id });
24546
+ } catch (error) {
24547
+ console.error(`Error processing image from ${src}:`, error);
24548
+ const tr = view.state.tr;
24549
+ removeImagePlaceholder(view.state, tr, id);
24550
+ view.dispatch(tr);
24551
+ }
24552
+ });
24553
+ };
24554
+ const ImagePositionPluginKey = new PluginKey("ImagePosition");
24555
+ const ImagePositionPlugin = ({ editor }) => {
24556
+ const { view } = editor;
24557
+ let shouldUpdate = false;
24558
+ return new Plugin({
24559
+ name: "ImagePositionPlugin",
24560
+ key: ImagePositionPluginKey,
24561
+ state: {
24562
+ init() {
24563
+ return DecorationSet.empty;
24564
+ },
24565
+ apply(tr, oldDecorationSet, oldState, newState) {
24566
+ if (!tr.docChanged) return oldDecorationSet;
24567
+ const decorations = getImagePositionDecorations(newState, view);
24568
+ return DecorationSet.create(newState.doc, decorations);
24569
+ }
24570
+ },
24571
+ view: () => {
24572
+ return {
24573
+ update: (view2, lastState) => {
24574
+ const pagination = PaginationPluginKey.getState(lastState);
24575
+ if (shouldUpdate) {
24576
+ shouldUpdate = false;
24577
+ const decorations = getImagePositionDecorations(lastState, view2);
24578
+ const updateTransaction = view2.state.tr.setMeta(ImagePositionPluginKey, { decorations });
24579
+ view2.dispatch(updateTransaction);
24580
+ }
24581
+ if (pagination?.isReadyToInit) {
24582
+ shouldUpdate = true;
24583
+ }
24584
+ }
24585
+ };
24586
+ },
24587
+ props: {
24588
+ decorations(state) {
24589
+ return this.getState(state);
24590
+ }
24591
+ }
24592
+ });
24593
+ };
24594
+ const getImagePositionDecorations = (state, view) => {
24595
+ let decorations = [];
24596
+ state.doc.descendants((node, pos) => {
24597
+ if (node.attrs.anchorData) {
24598
+ let style = "";
24599
+ let className = "";
24600
+ const { vRelativeFrom, alignH } = node.attrs.anchorData;
24601
+ const { size, padding, marginOffset } = node.attrs;
24602
+ const pageBreak = findPreviousDomNodeWithClass(view, pos, "pagination-break-wrapper");
24603
+ if (pageBreak) {
24604
+ switch (alignH) {
24605
+ case "left":
24606
+ style += "float: left; left: 0; margin-left: 0; ";
24607
+ break;
24608
+ case "right":
24609
+ style += "float: right; right: 0; margin-right: 0; ";
24610
+ break;
24611
+ case "center":
24612
+ style += "display: block; margin-left: auto; margin-right: auto; ";
24613
+ break;
24614
+ }
24615
+ const topPos = marginOffset.top !== void 0 ? marginOffset.top : pageBreak?.offsetTop + pageBreak?.offsetHeight;
24616
+ style += vRelativeFrom === "margin" ? `position: absolute; top: ${topPos}px; ` : "";
24617
+ if (vRelativeFrom === "margin") {
24618
+ const nextPos = view.posAtDOM(pageBreak, 1);
24619
+ if (nextPos < 0) {
24620
+ const $pos = view.state.doc.resolve(pos);
24621
+ decorations.push(
24622
+ Decoration.node(pos - 1, pos + $pos.parent.nodeSize - 1, {
24623
+ style: `height: ${size.height + parseInt(padding.top) + parseInt(padding.bottom)}px`
24624
+ })
24625
+ );
24626
+ }
24627
+ const imageBlock = document.createElement("div");
24628
+ imageBlock.className = "anchor-image-placeholder";
24629
+ imageBlock.style.float = alignH;
24630
+ imageBlock.style.width = size.width + parseInt(padding[alignH]) + "px";
24631
+ imageBlock.style.height = size.height + parseInt(padding.top) + parseInt(padding.bottom) + "px";
24632
+ decorations.push(Decoration.widget(nextPos, imageBlock, { key: "stable-key" }));
24633
+ }
24634
+ }
24635
+ decorations.push(Decoration.inline(pos, pos + node.nodeSize, { style, class: className }));
24636
+ }
24637
+ });
24638
+ return decorations;
24639
+ };
24640
+ const findPreviousDomNodeWithClass = (view, pos, className) => {
24641
+ let { node } = view.domAtPos(pos);
24642
+ if (node.nodeType === 3) {
24643
+ node = node.parentNode;
24644
+ }
24645
+ while (node) {
24646
+ if (node.classList && node.classList.contains(className)) {
24647
+ return node;
24648
+ }
24649
+ if (node.previousSibling) {
24650
+ node = node.previousSibling;
24651
+ while (node && node.lastChild) {
24652
+ node = node.lastChild;
24653
+ }
24654
+ } else {
24655
+ node = node.parentNode;
24656
+ }
24657
+ }
24658
+ return null;
24659
+ };
24660
+ const getRotationMargins = (w, h, angleDegrees) => {
24661
+ const rad = angleDegrees * (Math.PI / 180);
24662
+ const cos = Math.abs(Math.cos(rad));
24663
+ const sin = Math.abs(Math.sin(rad));
24664
+ const boundingWidth = w * cos + h * sin;
24665
+ const boundingHeight = w * sin + h * cos;
24666
+ const marginLeftRight = Math.round(Math.max(0, (boundingWidth - w) / 2));
24667
+ const marginTopBottom = Math.round(Math.max(0, (boundingHeight - h) / 2));
24668
+ return {
24669
+ horizontal: marginLeftRight,
24670
+ vertical: marginTopBottom
24671
+ };
24672
+ };
24673
+ const Image = Node$1.create({
24674
+ name: "image",
24675
+ group: "inline",
24676
+ inline: true,
24677
+ draggable: true,
24678
+ addOptions() {
24679
+ return {
24680
+ allowBase64: true,
24681
+ htmlAttributes: {
24682
+ style: "display: inline-block;",
24683
+ "aria-label": "Image node"
24684
+ }
24685
+ };
24686
+ },
24687
+ addStorage() {
24688
+ return {
24689
+ media: {}
24690
+ };
24691
+ },
24692
+ addAttributes() {
24693
+ return {
24694
+ src: {
24695
+ default: null,
24696
+ renderDOM: ({ src }) => {
24697
+ return {
24698
+ src: this.storage.media[src] ?? src
24699
+ };
24700
+ }
24701
+ },
24702
+ alt: {
24703
+ default: "Uploaded picture"
24704
+ },
24705
+ id: { rendered: false },
24706
+ title: {
24707
+ default: null
24708
+ },
24709
+ rId: {
24710
+ default: null,
24711
+ rendered: false
24712
+ },
24713
+ originalPadding: {
24714
+ default: null,
24715
+ rendered: false
24716
+ },
24717
+ originalAttributes: { rendered: false },
24718
+ wrapTopAndBottom: { rendered: false },
24719
+ anchorData: {
24720
+ default: null,
24721
+ rendered: false
24722
+ },
24723
+ isAnchor: { rendered: false },
24724
+ /**
24725
+ * @category Attribute
24726
+ * @param {Object} [transformData] - Transform data for image (turn and flip)
24727
+ * @param {number} [transformData.rotation] - Turn angle in degrees
24728
+ * @param {boolean} [transformData.verticalFlip] - Whether to flip vertically
24729
+ * @param {boolean} [transformData.horizontalFlip] - Whether to flip horizontally
24730
+ * @param {Object} [transformData.sizeExtension] - Size extension for image due to transformation
24731
+ * @param {number} [transformData.sizeExtension.left] - Left size extension for image
24732
+ * @param {number} [transformData.sizeExtension.top] - Top size extension for image
24733
+ * @param {number} [transformData.sizeExtension.right] - Right size extension for image
24734
+ * @param {number} [transformData.sizeExtension.bottom] - Bottom size extension for image
24735
+ *
24736
+ * @private
24737
+ */
24738
+ transformData: {
24739
+ default: {},
24740
+ renderDOM: ({ transformData }) => {
24741
+ let style = "";
24742
+ if (transformData?.rotation) {
24743
+ style += `rotate(${Math.round(transformData.rotation)}deg) `;
24744
+ }
24745
+ if (transformData?.verticalFlip) {
24746
+ style += "scaleY(-1) ";
24747
+ }
24748
+ if (transformData?.horizontalFlip) {
24749
+ style += "scaleX(-1) ";
24750
+ }
24751
+ style = style.trim();
24752
+ if (style.length > 0) {
24753
+ return { style: `transform: ${style};` };
24754
+ }
24755
+ return;
24756
+ }
24757
+ },
24758
+ /**
24759
+ * @category Attribute
24760
+ * @param {boolean} [simplePos] - Simple positioning flag
24761
+ * @private
24762
+ */
24763
+ simplePos: { rendered: false },
24764
+ wrapText: { rendered: false },
24765
+ extension: { rendered: false },
24766
+ size: {
24767
+ default: {},
24768
+ renderDOM: ({ size, extension }) => {
24769
+ let style = "";
24770
+ let { width, height } = size ?? {};
24771
+ if (width) style += `width: ${width}px;`;
24772
+ if (height && ["emf", "wmf"].includes(extension))
24773
+ style += `height: ${height}px; border: 1px solid black; position: absolute;`;
24774
+ else if (height) style += "height: auto;";
24775
+ return { style };
24776
+ }
24777
+ },
24778
+ padding: {
24779
+ default: {},
24780
+ renderDOM: ({ size = {}, padding, marginOffset, transformData }) => {
24781
+ let { left: left2 = 0, top: top2 = 0, bottom: bottom2 = 0, right: right2 = 0 } = padding ?? {};
24782
+ const { rotation } = transformData ?? {};
24783
+ const { height, width } = size ?? {};
24784
+ if (rotation && height && width) {
24785
+ const { horizontal, vertical } = getRotationMargins(width, height, rotation);
24786
+ left2 += horizontal;
24787
+ right2 += horizontal;
24788
+ top2 += vertical;
24789
+ bottom2 += vertical;
24790
+ }
24791
+ let style = "";
24792
+ if (left2 && marginOffset?.left == null) style += `margin-left: ${left2}px;`;
24793
+ if (top2 && marginOffset?.top == null) style += `margin-top: ${top2}px;`;
24794
+ if (bottom2) style += `margin-bottom: ${bottom2}px;`;
24795
+ if (right2) style += `margin-right: ${right2}px;`;
24796
+ return { style };
24797
+ }
24798
+ },
24799
+ marginOffset: {
24800
+ default: {},
24801
+ renderDOM: ({ marginOffset, anchorData, transformData, size }) => {
24802
+ const hasAnchorData = Boolean(anchorData);
24803
+ const hasMarginOffsets = marginOffset?.left != null || marginOffset?.top != null;
24804
+ if (!hasAnchorData && !hasMarginOffsets) return {};
24805
+ const relativeFromPageV = anchorData?.vRelativeFrom === "page";
24806
+ const maxMarginV = 500;
24807
+ const baseLeft = marginOffset?.left ?? 0;
24808
+ const baseTop = marginOffset?.top ?? 0;
24809
+ let rotationLeft = 0;
24810
+ let rotationTop = 0;
24811
+ const { rotation } = transformData ?? {};
24812
+ const { height, width } = size ?? {};
24813
+ if (rotation && height && width) {
24814
+ const { horizontal, vertical } = getRotationMargins(width, height, rotation);
24815
+ rotationLeft = horizontal;
24816
+ rotationTop = vertical;
24817
+ }
24818
+ const left2 = baseLeft + rotationLeft;
24819
+ const top2 = baseTop + rotationTop;
24820
+ let style = "";
24821
+ if (left2) style += `margin-left: ${left2}px;`;
24822
+ if (top2) {
24823
+ if (relativeFromPageV && top2 >= maxMarginV) style += `margin-top: ${maxMarginV}px;`;
24824
+ else style += `margin-top: ${top2}px;`;
24825
+ }
24826
+ if (!style) return {};
24827
+ return { style };
24828
+ }
24829
+ },
24830
+ style: {
24831
+ default: null,
24832
+ rendered: true,
24833
+ renderDOM: ({ style }) => {
24834
+ if (!style) return {};
24835
+ return { style };
24836
+ }
24837
+ }
24838
+ };
24839
+ },
24840
+ parseDOM() {
24841
+ return [
24842
+ {
24843
+ tag: this.options.allowBase64 ? "img[src]" : 'img[src]:not([src^="data:"])'
24844
+ }
24845
+ ];
24846
+ },
24847
+ renderDOM({ htmlAttributes }) {
24848
+ return ["img", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
24849
+ },
24850
+ addCommands() {
24851
+ return {
24852
+ /**
24853
+ * Insert an image at the current position
24854
+ * @category Command
24855
+ * @param {ImageInsertOptions} options - Image insertion options
24856
+ * @example
24857
+ * editor.commands.setImage({ src: 'https://example.com/image.jpg' })
24858
+ * editor.commands.setImage({
24859
+ * src: 'data:image/png;base64,...',
24860
+ * alt: 'Company logo',
24861
+ * size: { width: 200 }
24862
+ * })
24863
+ * @note Supports URLs, relative paths, and base64 data URIs
24864
+ */
24865
+ setImage: (options) => ({ commands: commands2 }) => {
24866
+ return commands2.insertContent({
24867
+ type: this.name,
24868
+ attrs: options
24869
+ });
24870
+ }
24871
+ };
24872
+ },
24873
+ addPmPlugins() {
24874
+ return [ImageRegistrationPlugin({ editor: this.editor }), ImagePositionPlugin({ editor: this.editor })];
24875
+ }
24876
+ });
24877
+ const ACCEPT_IMAGE_TYPES = [".jpg", ".jpeg", ".png", "image/jpeg", "image/png"];
24878
+ const getFileOpener = () => {
24879
+ let fileInput = document.createElement("input");
24880
+ fileInput.type = "file";
24881
+ let acceptTypes = ACCEPT_IMAGE_TYPES;
24882
+ fileInput.accept = acceptTypes.join(",");
24883
+ const openFile = () => {
24884
+ return new Promise((resolve, reject) => {
24885
+ fileInput.onchange = async () => {
24886
+ const files = fileInput.files;
24887
+ if (!files) return resolve(null);
24888
+ const file = files.item(0);
24889
+ if (!file) return resolve(null);
24890
+ return resolve({ file });
24891
+ };
24892
+ fileInput.oncancel = () => resolve(null);
24893
+ fileInput.onerror = reject;
24894
+ fileInput.click();
24895
+ });
24896
+ };
24897
+ return openFile;
24898
+ };
24695
24899
  const BookmarkStart = Node$1.create({
24696
24900
  name: "bookmarkStart",
24697
24901
  group: "inline",
@@ -24730,60 +24934,135 @@ const BookmarkStart = Node$1.create({
24730
24934
  */
24731
24935
  id: {
24732
24936
  default: null,
24733
- renderDOM: ({ id }) => {
24734
- if (id) return { id };
24937
+ renderDOM: ({ id }) => {
24938
+ if (id) return { id };
24939
+ return {};
24940
+ }
24941
+ }
24942
+ };
24943
+ },
24944
+ renderDOM({ htmlAttributes }) {
24945
+ return ["a", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
24946
+ },
24947
+ addCommands() {
24948
+ return {
24949
+ /**
24950
+ * Insert a bookmark at the current position
24951
+ * @category Command
24952
+ * @param {BookmarkConfig} config - Bookmark configuration
24953
+ * @returns {Function} Command function
24954
+ * @example
24955
+ * // Insert a named bookmark
24956
+ * insertBookmark({ name: 'chapter1' })
24957
+ *
24958
+ * // Insert with ID
24959
+ * insertBookmark({ name: 'introduction', id: 'intro-001' })
24960
+ * @note Bookmarks are invisible markers for navigation and cross-references
24961
+ */
24962
+ insertBookmark: (config) => ({ commands: commands2 }) => {
24963
+ return commands2.insertContent({
24964
+ type: this.name,
24965
+ attrs: config
24966
+ });
24967
+ },
24968
+ /**
24969
+ * Navigate to a bookmark by name
24970
+ * @category Command
24971
+ * @param {string} name - Bookmark name to navigate to
24972
+ * @returns {Function} Command function
24973
+ * @example
24974
+ * goToBookmark('chapter1')
24975
+ * @note Scrolls the document to the bookmark position
24976
+ */
24977
+ goToBookmark: (name) => ({ editor, tr }) => {
24978
+ const { doc: doc2 } = tr;
24979
+ let targetPos = null;
24980
+ doc2.descendants((node, pos) => {
24981
+ if (node.type.name === "bookmarkStart" && node.attrs.name === name) {
24982
+ targetPos = pos;
24983
+ return false;
24984
+ }
24985
+ });
24986
+ if (targetPos !== null) {
24987
+ editor.commands.focus(targetPos);
24988
+ return true;
24989
+ }
24990
+ return false;
24991
+ }
24992
+ };
24993
+ }
24994
+ });
24995
+ const BookmarkEnd = Node$1.create({
24996
+ name: "bookmarkEnd",
24997
+ group: "inline",
24998
+ inline: true,
24999
+ atom: true,
25000
+ addOptions() {
25001
+ return {
25002
+ /**
25003
+ * @typedef {Object} BookmarkEndOptions
25004
+ * @category Options
25005
+ * @property {Object} [htmlAttributes] - HTML attributes for the bookmark end element
25006
+ */
25007
+ htmlAttributes: {
25008
+ style: "height: 0; width: 0; display: none;",
25009
+ "aria-label": "Bookmark end node",
25010
+ role: "none"
25011
+ }
25012
+ };
25013
+ },
25014
+ addAttributes() {
25015
+ return {
25016
+ /**
25017
+ * @category Attribute
25018
+ * @param {string} [id] - Unique identifier matching the corresponding bookmarkStart
25019
+ */
25020
+ id: {
25021
+ default: null,
25022
+ renderDOM: ({ id }) => {
25023
+ if (id) return { "data-bookmark-end-id": id };
25024
+ return {};
25025
+ }
25026
+ },
25027
+ /**
25028
+ * @category Attribute
25029
+ * @param {string} [displacedByCustomXml] - Indicates if bookmark was displaced by custom XML
25030
+ */
25031
+ displacedByCustomXml: {
25032
+ default: null,
25033
+ renderDOM: ({ displacedByCustomXml }) => {
25034
+ if (displacedByCustomXml) return { "data-displaced-by-custom-xml": displacedByCustomXml };
24735
25035
  return {};
24736
25036
  }
25037
+ },
25038
+ // Pass-through attributes that may not be used in rendering but should be preserved
25039
+ colFirst: {
25040
+ default: null
25041
+ },
25042
+ colLast: {
25043
+ default: null
24737
25044
  }
24738
25045
  };
24739
25046
  },
24740
25047
  renderDOM({ htmlAttributes }) {
24741
- return ["a", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
25048
+ return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
24742
25049
  },
24743
25050
  addCommands() {
24744
25051
  return {
24745
25052
  /**
24746
- * Insert a bookmark at the current position
25053
+ * Insert a bookmark end marker at the current position
24747
25054
  * @category Command
24748
- * @param {BookmarkConfig} config - Bookmark configuration
25055
+ * @param {string} id - The bookmark ID to match with bookmarkStart
24749
25056
  * @returns {Function} Command function
24750
25057
  * @example
24751
- * // Insert a named bookmark
24752
- * insertBookmark({ name: 'chapter1' })
24753
- *
24754
- * // Insert with ID
24755
- * insertBookmark({ name: 'introduction', id: 'intro-001' })
24756
- * @note Bookmarks are invisible markers for navigation and cross-references
25058
+ * // Insert bookmark end
25059
+ * insertBookmarkEnd('bookmark-001')
24757
25060
  */
24758
- insertBookmark: (config) => ({ commands: commands2 }) => {
25061
+ insertBookmarkEnd: (id) => ({ commands: commands2 }) => {
24759
25062
  return commands2.insertContent({
24760
25063
  type: this.name,
24761
- attrs: config
24762
- });
24763
- },
24764
- /**
24765
- * Navigate to a bookmark by name
24766
- * @category Command
24767
- * @param {string} name - Bookmark name to navigate to
24768
- * @returns {Function} Command function
24769
- * @example
24770
- * goToBookmark('chapter1')
24771
- * @note Scrolls the document to the bookmark position
24772
- */
24773
- goToBookmark: (name) => ({ editor, tr }) => {
24774
- const { doc: doc2 } = tr;
24775
- let targetPos = null;
24776
- doc2.descendants((node, pos) => {
24777
- if (node.type.name === "bookmarkStart" && node.attrs.name === name) {
24778
- targetPos = pos;
24779
- return false;
24780
- }
25064
+ attrs: { id }
24781
25065
  });
24782
- if (targetPos !== null) {
24783
- editor.commands.focus(targetPos);
24784
- return true;
24785
- }
24786
- return false;
24787
25066
  }
24788
25067
  };
24789
25068
  }
@@ -24868,6 +25147,14 @@ const PageNumber = Node$1.create({
24868
25147
  },
24869
25148
  addCommands() {
24870
25149
  return {
25150
+ /**
25151
+ * Insert an automatic page number
25152
+ * @category Command
25153
+ * @returns {Function} Command function
25154
+ * @example
25155
+ * editor.commands.addAutoPageNumber()
25156
+ * @note Only works in header/footer contexts
25157
+ */
24871
25158
  addAutoPageNumber: () => ({ tr, dispatch, state, editor }) => {
24872
25159
  const { options } = editor;
24873
25160
  if (!options.isHeaderOrFooter) return false;
@@ -24930,6 +25217,14 @@ const TotalPageCount = Node$1.create({
24930
25217
  },
24931
25218
  addCommands() {
24932
25219
  return {
25220
+ /**
25221
+ * Insert total page count
25222
+ * @category Command
25223
+ * @returns {Function} Command function
25224
+ * @example
25225
+ * editor.commands.addTotalPageCount()
25226
+ * @note Only works in header/footer contexts
25227
+ */
24933
25228
  addTotalPageCount: () => ({ tr, dispatch, state, editor }) => {
24934
25229
  const { options } = editor;
24935
25230
  if (!options.isHeaderOrFooter) return false;
@@ -24986,7 +25281,9 @@ class AutoPageNumberNodeView {
24986
25281
  this.dom = __privateMethod(this, _AutoPageNumberNodeView_instances, renderDom_fn).call(this, node, htmlAttributes);
24987
25282
  }
24988
25283
  update(node) {
24989
- if (node.type !== this.node.type) return false;
25284
+ const incomingType = node?.type?.name;
25285
+ const currentType = this.node?.type?.name;
25286
+ if (!incomingType || incomingType !== currentType) return false;
24990
25287
  this.node = node;
24991
25288
  return true;
24992
25289
  }
@@ -25004,8 +25301,8 @@ renderDom_fn = function(node, htmlAttributes) {
25004
25301
  __privateMethod(this, _AutoPageNumberNodeView_instances, scheduleUpdateNodeStyle_fn).call(this, currentPos, marks);
25005
25302
  Object.assign(nodeContent.style, styles);
25006
25303
  nodeContent.appendChild(content);
25007
- Object.entries(htmlAttributes).forEach(([key, value]) => {
25008
- if (value) nodeContent.setAttribute(key, value);
25304
+ Object.entries(htmlAttributes).forEach(([key2, value]) => {
25305
+ if (value) nodeContent.setAttribute(key2, value);
25009
25306
  });
25010
25307
  return nodeContent;
25011
25308
  };
@@ -25071,8 +25368,8 @@ const processMarks = (marks) => {
25071
25368
  break;
25072
25369
  default:
25073
25370
  if (attrs?.style) {
25074
- Object.entries(attrs.style).forEach(([key, value]) => {
25075
- styles[key] = value;
25371
+ Object.entries(attrs.style).forEach(([key2, value]) => {
25372
+ styles[key2] = value;
25076
25373
  });
25077
25374
  }
25078
25375
  break;
@@ -25194,11 +25491,6 @@ const ContentBlock = Node$1.create({
25194
25491
  inline: true,
25195
25492
  addOptions() {
25196
25493
  return {
25197
- /**
25198
- * @typedef {Object} ContentBlockOptions
25199
- * @category Options
25200
- * @property {Object} [htmlAttributes] - HTML attributes for the block element
25201
- */
25202
25494
  htmlAttributes: {
25203
25495
  contenteditable: false
25204
25496
  }
@@ -25206,10 +25498,6 @@ const ContentBlock = Node$1.create({
25206
25498
  },
25207
25499
  addAttributes() {
25208
25500
  return {
25209
- /**
25210
- * @category Attribute
25211
- * @param {boolean} [horizontalRule=false] - Whether this block is a horizontal rule
25212
- */
25213
25501
  horizontalRule: {
25214
25502
  default: false,
25215
25503
  renderDOM: ({ horizontalRule }) => {
@@ -25217,10 +25505,6 @@ const ContentBlock = Node$1.create({
25217
25505
  return { "data-horizontal-rule": "true" };
25218
25506
  }
25219
25507
  },
25220
- /**
25221
- * @category Attribute
25222
- * @param {ContentBlockSize} [size] - Size and position of the content block
25223
- */
25224
25508
  size: {
25225
25509
  default: null,
25226
25510
  renderDOM: ({ size }) => {
@@ -25234,10 +25518,6 @@ const ContentBlock = Node$1.create({
25234
25518
  return { style };
25235
25519
  }
25236
25520
  },
25237
- /**
25238
- * @category Attribute
25239
- * @param {string} [background] - Background color for the block
25240
- */
25241
25521
  background: {
25242
25522
  default: null,
25243
25523
  renderDOM: (attrs) => {
@@ -25247,19 +25527,9 @@ const ContentBlock = Node$1.create({
25247
25527
  };
25248
25528
  }
25249
25529
  },
25250
- /**
25251
- * @private
25252
- * @category Attribute
25253
- * @param {Object} [drawingContent] - Internal drawing data
25254
- */
25255
25530
  drawingContent: {
25256
25531
  rendered: false
25257
25532
  },
25258
- /**
25259
- * @private
25260
- * @category Attribute
25261
- * @param {Object} [attributes] - Additional internal attributes
25262
- */
25263
25533
  attributes: {
25264
25534
  rendered: false
25265
25535
  }
@@ -25280,9 +25550,8 @@ const ContentBlock = Node$1.create({
25280
25550
  /**
25281
25551
  * Insert a horizontal rule
25282
25552
  * @category Command
25283
- * @returns {Function} Command function
25284
25553
  * @example
25285
- * insertHorizontalRule()
25554
+ * editor.commands.insertHorizontalRule()
25286
25555
  * @note Creates a visual separator between content sections
25287
25556
  */
25288
25557
  insertHorizontalRule: () => ({ commands: commands2 }) => {
@@ -25299,13 +25568,13 @@ const ContentBlock = Node$1.create({
25299
25568
  * Insert a content block
25300
25569
  * @category Command
25301
25570
  * @param {ContentBlockConfig} config - Block configuration
25302
- * @returns {Function} Command function
25303
25571
  * @example
25304
25572
  * // Insert a spacer block
25305
- * insertContentBlock({ size: { height: 20 } })
25573
+ * editor.commands.insertContentBlock({ size: { height: 20 } })
25306
25574
  *
25575
+ * @example
25307
25576
  * // Insert a colored divider
25308
- * insertContentBlock({
25577
+ * editor.commands.insertContentBlock({
25309
25578
  * size: { width: '50%', height: 3 },
25310
25579
  * background: '#3b82f6'
25311
25580
  * })
@@ -25320,57 +25589,353 @@ const ContentBlock = Node$1.create({
25320
25589
  };
25321
25590
  }
25322
25591
  });
25592
+ class StructuredContentViewBase {
25593
+ constructor(props) {
25594
+ __publicField(this, "node");
25595
+ __publicField(this, "view");
25596
+ __publicField(this, "getPos");
25597
+ __publicField(this, "decorations");
25598
+ __publicField(this, "innerDecorations");
25599
+ __publicField(this, "editor");
25600
+ __publicField(this, "extension");
25601
+ __publicField(this, "htmlAttributes");
25602
+ __publicField(this, "root");
25603
+ __publicField(this, "isDragging", false);
25604
+ this.node = props.node;
25605
+ this.view = props.editor.view;
25606
+ this.getPos = props.getPos;
25607
+ this.decorations = props.decorations;
25608
+ this.innerDecorations = props.innerDecorations;
25609
+ this.editor = props.editor;
25610
+ this.extension = props.extension;
25611
+ this.htmlAttributes = props.htmlAttributes;
25612
+ this.mount(props);
25613
+ }
25614
+ mount() {
25615
+ return;
25616
+ }
25617
+ get dom() {
25618
+ return this.root;
25619
+ }
25620
+ get contentDOM() {
25621
+ return null;
25622
+ }
25623
+ update(node, decorations, innerDecorations) {
25624
+ if (node.type !== this.node.type) {
25625
+ return false;
25626
+ }
25627
+ this.node = node;
25628
+ this.decorations = decorations;
25629
+ this.innerDecorations = innerDecorations;
25630
+ this.updateHTMLAttributes();
25631
+ return true;
25632
+ }
25633
+ stopEvent(event) {
25634
+ if (!this.dom) return false;
25635
+ const target = event.target;
25636
+ const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target);
25637
+ if (!isInElement) return false;
25638
+ const isDragEvent = event.type.startsWith("drag");
25639
+ const isDropEvent = event.type === "drop";
25640
+ const isInput = ["INPUT", "BUTTON", "SELECT", "TEXTAREA"].includes(target.tagName) || target.isContentEditable;
25641
+ if (isInput && !isDropEvent && !isDragEvent) return true;
25642
+ const { isEditable } = this.editor;
25643
+ const { isDragging } = this;
25644
+ const isDraggable = !!this.node.type.spec.draggable;
25645
+ const isSelectable = NodeSelection.isSelectable(this.node);
25646
+ const isCopyEvent = event.type === "copy";
25647
+ const isPasteEvent = event.type === "paste";
25648
+ const isCutEvent = event.type === "cut";
25649
+ const isClickEvent = event.type === "mousedown";
25650
+ if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
25651
+ event.preventDefault();
25652
+ }
25653
+ if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
25654
+ event.preventDefault();
25655
+ return false;
25656
+ }
25657
+ if (isDraggable && isEditable && !isDragging && isClickEvent) {
25658
+ const dragHandle = target.closest("[data-drag-handle]");
25659
+ const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle));
25660
+ if (isValidDragHandle) {
25661
+ this.isDragging = true;
25662
+ document.addEventListener(
25663
+ "dragend",
25664
+ () => {
25665
+ this.isDragging = false;
25666
+ },
25667
+ { once: true }
25668
+ );
25669
+ document.addEventListener(
25670
+ "drop",
25671
+ () => {
25672
+ this.isDragging = false;
25673
+ },
25674
+ { once: true }
25675
+ );
25676
+ document.addEventListener(
25677
+ "mouseup",
25678
+ () => {
25679
+ this.isDragging = false;
25680
+ },
25681
+ { once: true }
25682
+ );
25683
+ }
25684
+ }
25685
+ if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || isClickEvent && isSelectable) {
25686
+ return false;
25687
+ }
25688
+ return true;
25689
+ }
25690
+ ignoreMutation(mutation) {
25691
+ if (!this.dom || !this.contentDOM) return true;
25692
+ if (this.node.isLeaf || this.node.isAtom) return true;
25693
+ if (mutation.type === "selection") return false;
25694
+ if (this.contentDOM === mutation.target && mutation.type === "attributes") return true;
25695
+ if (this.contentDOM.contains(mutation.target)) return false;
25696
+ return true;
25697
+ }
25698
+ destroy() {
25699
+ this.dom.remove();
25700
+ this.contentDOM?.remove();
25701
+ }
25702
+ updateAttributes(attrs) {
25703
+ const pos = this.getPos();
25704
+ if (typeof pos !== "number") {
25705
+ return;
25706
+ }
25707
+ return this.view.dispatch(
25708
+ this.view.state.tr.setNodeMarkup(pos, void 0, {
25709
+ ...this.node.attrs,
25710
+ ...attrs
25711
+ })
25712
+ );
25713
+ }
25714
+ updateHTMLAttributes() {
25715
+ const { extensionService } = this.editor;
25716
+ const { attributes } = extensionService;
25717
+ const extensionAttrs = attributes.filter((i) => i.type === this.node.type.name);
25718
+ this.htmlAttributes = Attribute.getAttributesToRender(this.node, extensionAttrs);
25719
+ }
25720
+ createDragHandle() {
25721
+ const dragHandle = document.createElement("span");
25722
+ dragHandle.classList.add("sd-structured-content-draggable");
25723
+ dragHandle.draggable = true;
25724
+ dragHandle.contentEditable = "false";
25725
+ dragHandle.dataset.dragHandle = "";
25726
+ const textElement = document.createElement("span");
25727
+ textElement.textContent = "Structured content";
25728
+ dragHandle.append(textElement);
25729
+ return dragHandle;
25730
+ }
25731
+ onDragStart(event) {
25732
+ const { view } = this.editor;
25733
+ const target = event.target;
25734
+ const dragHandle = target.nodeType === 3 ? target.parentElement?.closest("[data-drag-handle]") : target.closest("[data-drag-handle]");
25735
+ if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
25736
+ return;
25737
+ }
25738
+ let x = 0;
25739
+ let y = 0;
25740
+ if (this.dom !== dragHandle) {
25741
+ const domBox = this.dom.getBoundingClientRect();
25742
+ const handleBox = dragHandle.getBoundingClientRect();
25743
+ const offsetX = event.offsetX ?? event.nativeEvent?.offsetX;
25744
+ const offsetY = event.offsetY ?? event.nativeEvent?.offsetY;
25745
+ x = handleBox.x - domBox.x + offsetX;
25746
+ y = handleBox.y - domBox.y + offsetY;
25747
+ }
25748
+ event.dataTransfer?.setDragImage(this.dom, x, y);
25749
+ const pos = this.getPos();
25750
+ if (typeof pos !== "number") {
25751
+ return;
25752
+ }
25753
+ const selection = NodeSelection.create(view.state.doc, pos);
25754
+ const transaction = view.state.tr.setSelection(selection);
25755
+ view.dispatch(transaction);
25756
+ }
25757
+ }
25758
+ class StructuredContentInlineView extends StructuredContentViewBase {
25759
+ constructor(props) {
25760
+ super(props);
25761
+ }
25762
+ mount() {
25763
+ this.buildView();
25764
+ }
25765
+ get contentDOM() {
25766
+ const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass$1}`);
25767
+ return contentElement || null;
25768
+ }
25769
+ createElement() {
25770
+ const element = document.createElement("span");
25771
+ element.classList.add(structuredContentClass$1);
25772
+ element.setAttribute("data-structured-content", "");
25773
+ const contentElement = document.createElement("span");
25774
+ contentElement.classList.add(structuredContentInnerClass$1);
25775
+ element.append(contentElement);
25776
+ const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
25777
+ updateDOMAttributes(element, { ...domAttrs });
25778
+ return { element, contentElement };
25779
+ }
25780
+ buildView() {
25781
+ const { element } = this.createElement();
25782
+ const dragHandle = this.createDragHandle();
25783
+ element.prepend(dragHandle);
25784
+ element.addEventListener("dragstart", (e) => this.onDragStart(e));
25785
+ this.root = element;
25786
+ }
25787
+ updateView() {
25788
+ const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
25789
+ updateDOMAttributes(this.dom, { ...domAttrs });
25790
+ }
25791
+ update(node, decorations, innerDecorations) {
25792
+ const result = super.update(node, decorations, innerDecorations);
25793
+ if (!result) return false;
25794
+ this.updateView();
25795
+ return true;
25796
+ }
25797
+ }
25798
+ const structuredContentClass$1 = "sd-structured-content";
25799
+ const structuredContentInnerClass$1 = "sd-structured-content__content";
25323
25800
  const StructuredContent = Node$1.create({
25324
25801
  name: "structuredContent",
25325
- group: "inline",
25802
+ group: "inline structuredContent",
25326
25803
  inline: true,
25327
25804
  content: "inline*",
25805
+ isolating: true,
25806
+ atom: false,
25807
+ // false - has editable content.
25808
+ draggable: true,
25328
25809
  addOptions() {
25329
25810
  return {
25330
- structuredContentClass: "sd-structured-content-tag",
25331
25811
  htmlAttributes: {
25812
+ class: structuredContentClass$1,
25332
25813
  "aria-label": "Structured content node"
25333
25814
  }
25334
25815
  };
25335
25816
  },
25336
- parseDOM() {
25337
- return [{ tag: `span.${this.options.structuredContentClass}` }];
25338
- },
25339
- renderDOM({ htmlAttributes }) {
25340
- return ["span", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
25341
- },
25342
25817
  addAttributes() {
25343
25818
  return {
25819
+ id: {
25820
+ default: null,
25821
+ parseDOM: (elem) => elem.getAttribute("data-id"),
25822
+ renderDOM: (attrs) => {
25823
+ if (!attrs.id) return {};
25824
+ return { "data-id": attrs.id };
25825
+ }
25826
+ },
25344
25827
  sdtPr: {
25345
25828
  rendered: false
25346
25829
  }
25347
25830
  };
25831
+ },
25832
+ parseDOM() {
25833
+ return [{ tag: "span[data-structured-content]" }];
25834
+ },
25835
+ renderDOM({ htmlAttributes }) {
25836
+ return [
25837
+ "span",
25838
+ Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
25839
+ "data-structured-content": ""
25840
+ }),
25841
+ 0
25842
+ ];
25843
+ },
25844
+ addNodeView() {
25845
+ return (props) => {
25846
+ return new StructuredContentInlineView({ ...props });
25847
+ };
25348
25848
  }
25349
25849
  });
25850
+ class StructuredContentBlockView extends StructuredContentViewBase {
25851
+ constructor(props) {
25852
+ super(props);
25853
+ }
25854
+ mount() {
25855
+ this.buildView();
25856
+ }
25857
+ get contentDOM() {
25858
+ const contentElement = this.dom?.querySelector(`.${structuredContentInnerClass}`);
25859
+ return contentElement || null;
25860
+ }
25861
+ createElement() {
25862
+ const element = document.createElement("div");
25863
+ element.classList.add(structuredContentClass);
25864
+ element.setAttribute("data-structured-content-block", "");
25865
+ const contentElement = document.createElement("div");
25866
+ contentElement.classList.add(structuredContentInnerClass);
25867
+ element.append(contentElement);
25868
+ const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
25869
+ updateDOMAttributes(element, { ...domAttrs });
25870
+ return { element, contentElement };
25871
+ }
25872
+ buildView() {
25873
+ const { element } = this.createElement();
25874
+ const dragHandle = this.createDragHandle();
25875
+ element.prepend(dragHandle);
25876
+ element.addEventListener("dragstart", (e) => this.onDragStart(e));
25877
+ this.root = element;
25878
+ }
25879
+ updateView() {
25880
+ const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
25881
+ updateDOMAttributes(this.dom, { ...domAttrs });
25882
+ }
25883
+ update(node, decorations, innerDecorations) {
25884
+ const result = super.update(node, decorations, innerDecorations);
25885
+ if (!result) return false;
25886
+ this.updateView();
25887
+ return true;
25888
+ }
25889
+ }
25890
+ const structuredContentClass = "sd-structured-content-block";
25891
+ const structuredContentInnerClass = "sd-structured-content-block__content";
25350
25892
  const StructuredContentBlock = Node$1.create({
25351
25893
  name: "structuredContentBlock",
25352
- group: "block",
25894
+ group: "block structuredContent",
25353
25895
  content: "block*",
25896
+ isolating: true,
25897
+ atom: false,
25898
+ // false - has editable content.
25899
+ draggable: true,
25354
25900
  addOptions() {
25355
25901
  return {
25356
- structuredContentClass: "sd-structured-content-tag",
25357
25902
  htmlAttributes: {
25903
+ class: structuredContentClass,
25358
25904
  "aria-label": "Structured content block node"
25359
25905
  }
25360
25906
  };
25361
25907
  },
25362
- parseDOM() {
25363
- return [{ tag: `div.${this.options.structuredContentClass}` }];
25364
- },
25365
- renderDOM({ htmlAttributes }) {
25366
- return ["div", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
25367
- },
25368
25908
  addAttributes() {
25369
25909
  return {
25910
+ id: {
25911
+ default: null,
25912
+ parseDOM: (elem) => elem.getAttribute("data-id"),
25913
+ renderDOM: (attrs) => {
25914
+ if (!attrs.id) return {};
25915
+ return { "data-id": attrs.id };
25916
+ }
25917
+ },
25370
25918
  sdtPr: {
25371
25919
  rendered: false
25372
25920
  }
25373
25921
  };
25922
+ },
25923
+ parseDOM() {
25924
+ return [{ tag: "div[data-structured-content-block]" }];
25925
+ },
25926
+ renderDOM({ htmlAttributes }) {
25927
+ return [
25928
+ "div",
25929
+ Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes, {
25930
+ "data-structured-content-block": ""
25931
+ }),
25932
+ 0
25933
+ ];
25934
+ },
25935
+ addNodeView() {
25936
+ return (props) => {
25937
+ return new StructuredContentBlockView({ ...props });
25938
+ };
25374
25939
  }
25375
25940
  });
25376
25941
  class DocumentSectionView {
@@ -25537,16 +26102,7 @@ const DocumentSection = Node$1.create({
25537
26102
  },
25538
26103
  addAttributes() {
25539
26104
  return {
25540
- /**
25541
- * @category Attribute
25542
- * @param {number} [id] - Unique section identifier
25543
- */
25544
26105
  id: {},
25545
- /**
25546
- * @private
25547
- * @category Attribute
25548
- * @param {string} [sdBlockId] - Internal block tracking
25549
- */
25550
26106
  sdBlockId: {
25551
26107
  default: null,
25552
26108
  keepOnSplit: false,
@@ -25555,25 +26111,9 @@ const DocumentSection = Node$1.create({
25555
26111
  return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
25556
26112
  }
25557
26113
  },
25558
- /**
25559
- * @category Attribute
25560
- * @param {string} [title] - Section display label
25561
- */
25562
26114
  title: {},
25563
- /**
25564
- * @category Attribute
25565
- * @param {string} [description] - Section metadata
25566
- */
25567
26115
  description: {},
25568
- /**
25569
- * @category Attribute
25570
- * @param {string} [sectionType] - Business classification (e.g., 'legal', 'pricing')
25571
- */
25572
26116
  sectionType: {},
25573
- /**
25574
- * @category Attribute
25575
- * @param {boolean} [isLocked=false] - Lock state preventing edits
25576
- */
25577
26117
  isLocked: { default: false }
25578
26118
  };
25579
26119
  },
@@ -25588,10 +26128,9 @@ const DocumentSection = Node$1.create({
25588
26128
  * Create a lockable content section
25589
26129
  * @category Command
25590
26130
  * @param {SectionCreate} [options={}] - Section configuration
25591
- * @returns {Function} Command - true if created, false if position invalid
25592
26131
  * @example
25593
- * createDocumentSection({
25594
- * id: 'legal-1',
26132
+ * editor.commands.createDocumentSection({
26133
+ * id: 1,
25595
26134
  * title: 'Terms & Conditions',
25596
26135
  * isLocked: true,
25597
26136
  * html: '<p>Legal content...</p>'
@@ -25672,9 +26211,8 @@ const DocumentSection = Node$1.create({
25672
26211
  /**
25673
26212
  * Remove section wrapper at cursor, preserving its content
25674
26213
  * @category Command
25675
- * @returns {Function} Command - true if removed, false if no section at position
25676
26214
  * @example
25677
- * removeSectionAtSelection()
26215
+ * editor.commands.removeSectionAtSelection()
25678
26216
  * @note Content stays in document, only section wrapper is removed
25679
26217
  */
25680
26218
  removeSectionAtSelection: () => ({ tr, dispatch }) => {
@@ -25700,9 +26238,8 @@ const DocumentSection = Node$1.create({
25700
26238
  * Delete section and all its content
25701
26239
  * @category Command
25702
26240
  * @param {number} id - Section to delete
25703
- * @returns {Function} Command - true if deleted, false if ID doesn't exist
25704
26241
  * @example
25705
- * removeSectionById(123)
26242
+ * editor.commands.removeSectionById(123)
25706
26243
  */
25707
26244
  removeSectionById: (id) => ({ tr, dispatch }) => {
25708
26245
  const sections = SectionHelpers.getAllSections(this.editor);
@@ -25722,9 +26259,8 @@ const DocumentSection = Node$1.create({
25722
26259
  * Lock section against edits
25723
26260
  * @category Command
25724
26261
  * @param {number} id - Section to lock
25725
- * @returns {Function} Command - true if locked, false if ID doesn't exist
25726
26262
  * @example
25727
- * lockSectionById(123)
26263
+ * editor.commands.lockSectionById(123)
25728
26264
  */
25729
26265
  lockSectionById: (id) => ({ tr, dispatch }) => {
25730
26266
  const sections = SectionHelpers.getAllSections(this.editor);
@@ -25741,16 +26277,10 @@ const DocumentSection = Node$1.create({
25741
26277
  * Modify section attributes or content
25742
26278
  * @category Command
25743
26279
  * @param {SectionUpdate} options - Changes to apply
25744
- * @returns {Function} Command - true if updated, false if ID doesn't exist
25745
26280
  * @example
25746
- * // Toggle lock
25747
- * updateSectionById({ id: 123, attrs: { isLocked: false } })
25748
- *
25749
- * // Replace content
25750
- * updateSectionById({ id: 123, html: '<p>New content</p>' })
25751
- *
25752
- * // Both
25753
- * updateSectionById({
26281
+ * editor.commands.updateSectionById({ id: 123, attrs: { isLocked: false } })
26282
+ * editor.commands.updateSectionById({ id: 123, html: '<p>New content</p>' })
26283
+ * editor.commands.updateSectionById({
25754
26284
  * id: 123,
25755
26285
  * html: '<p>Updated</p>',
25756
26286
  * attrs: { title: 'New Title' }
@@ -25800,11 +26330,10 @@ const BlockNode = Extension.create({
25800
26330
  * Replace a block node by its ID with new content
25801
26331
  * @category Command
25802
26332
  * @param {string} id - The sdBlockId of the node to replace
25803
- * @param {Object} contentNode - The replacement ProseMirror node
25804
- * @returns {Function} Command function
26333
+ * @param {ProseMirrorNode} contentNode - The replacement ProseMirror node
25805
26334
  * @example
25806
26335
  * const newParagraph = editor.schema.nodes.paragraph.create({}, editor.schema.text('New content'))
25807
- * replaceBlockNodeById('block-123', newParagraph)
26336
+ * editor.commands.replaceBlockNodeById('block-123', newParagraph)
25808
26337
  * @note The replacement node should have the same type as the original
25809
26338
  */
25810
26339
  replaceBlockNodeById: (id, contentNode) => ({ dispatch, tr }) => {
@@ -25827,9 +26356,8 @@ const BlockNode = Extension.create({
25827
26356
  * Delete a block node by its ID
25828
26357
  * @category Command
25829
26358
  * @param {string} id - The sdBlockId of the node to delete
25830
- * @returns {Function} Command function
25831
26359
  * @example
25832
- * deleteBlockNodeById('block-123')
26360
+ * editor.commands.deleteBlockNodeById('block-123')
25833
26361
  * @note Completely removes the node from the document
25834
26362
  */
25835
26363
  deleteBlockNodeById: (id) => ({ dispatch, tr }) => {
@@ -25853,11 +26381,10 @@ const BlockNode = Extension.create({
25853
26381
  * @category Command
25854
26382
  * @param {string} id - The sdBlockId of the node to update
25855
26383
  * @param {Object} attrs - Attributes to update
25856
- * @returns {Function} Command function
25857
26384
  * @example
25858
- * updateBlockNodeAttributes('block-123', { textAlign: 'center' })
26385
+ * editor.commands.updateBlockNodeAttributes('block-123', { textAlign: 'center' })
25859
26386
  * @example
25860
- * updateBlockNodeAttributes('block-123', { indent: { left: 20 } })
26387
+ * editor.commands.updateBlockNodeAttributes('block-123', { indent: { left: 20 } })
25861
26388
  * @note Merges new attributes with existing ones
25862
26389
  */
25863
26390
  updateBlockNodeAttributes: (id, attrs = {}) => ({ dispatch, tr }) => {
@@ -25951,7 +26478,7 @@ const BlockNode = Extension.create({
25951
26478
  key: BlockNodePluginKey,
25952
26479
  appendTransaction: (transactions, _oldState, newState) => {
25953
26480
  if (hasInitialized && !transactions.some((tr2) => tr2.docChanged)) return null;
25954
- if (hasInitialized && !checkForNewBlockNodesInTrs(transactions)) return null;
26481
+ if (hasInitialized && !checkForNewBlockNodesInTrs([...transactions])) return null;
25955
26482
  const { tr } = newState;
25956
26483
  let changed = false;
25957
26484
  newState.doc.descendants((node, pos) => {
@@ -26030,9 +26557,8 @@ const TextStyle = Mark.create({
26030
26557
  /**
26031
26558
  * Remove empty text style marks
26032
26559
  * @category Command
26033
- * @returns {Function} Command function - Removes mark if no attributes present
26034
26560
  * @example
26035
- * removeEmptyTextStyle()
26561
+ * editor.commands.removeEmptyTextStyle()
26036
26562
  * @note Cleanup utility to prevent empty span elements
26037
26563
  * @note Automatically checks if any style attributes exist before removal
26038
26564
  */
@@ -26054,10 +26580,6 @@ const Bold = Mark.create({
26054
26580
  },
26055
26581
  addAttributes() {
26056
26582
  return {
26057
- /**
26058
- * @category Attribute
26059
- * @param {string} [value] - Bold weight value ('0' renders as normal)
26060
- */
26061
26583
  value: {
26062
26584
  default: null,
26063
26585
  renderDOM: (attrs) => {
@@ -26086,26 +26608,23 @@ const Bold = Mark.create({
26086
26608
  /**
26087
26609
  * Apply bold formatting
26088
26610
  * @category Command
26089
- * @returns {Function} Command
26090
26611
  * @example
26091
- * setBold()
26612
+ * editor.commands.setBold()
26092
26613
  * @note '0' renders as normal weight
26093
26614
  */
26094
26615
  setBold: () => ({ commands: commands2 }) => commands2.setMark(this.name),
26095
26616
  /**
26096
26617
  * Remove bold formatting
26097
26618
  * @category Command
26098
- * @returns {Function} Command
26099
26619
  * @example
26100
- * unsetBold()
26620
+ * editor.commands.unsetBold()
26101
26621
  */
26102
26622
  unsetBold: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
26103
26623
  /**
26104
26624
  * Toggle bold formatting
26105
26625
  * @category Command
26106
- * @returns {Function} Command
26107
26626
  * @example
26108
- * toggleBold()
26627
+ * editor.commands.toggleBold()
26109
26628
  */
26110
26629
  toggleBold: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
26111
26630
  };
@@ -26140,25 +26659,22 @@ const Italic = Mark.create({
26140
26659
  /**
26141
26660
  * Apply italic formatting
26142
26661
  * @category Command
26143
- * @returns {Function} Command
26144
26662
  * @example
26145
- * setItalic()
26663
+ * editor.commands.setItalic()
26146
26664
  */
26147
26665
  setItalic: () => ({ commands: commands2 }) => commands2.setMark(this.name),
26148
26666
  /**
26149
26667
  * Remove italic formatting
26150
26668
  * @category Command
26151
- * @returns {Function} Command
26152
26669
  * @example
26153
- * unsetItalic()
26670
+ * editor.commands.unsetItalic()
26154
26671
  */
26155
26672
  unsetItalic: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
26156
26673
  /**
26157
26674
  * Toggle italic formatting
26158
26675
  * @category Command
26159
- * @returns {Function} Command
26160
26676
  * @example
26161
- * toggleItalic()
26677
+ * editor.commands.toggleItalic()
26162
26678
  */
26163
26679
  toggleItalic: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
26164
26680
  };
@@ -26242,10 +26758,6 @@ const Highlight = Mark.create({
26242
26758
  },
26243
26759
  addAttributes() {
26244
26760
  return {
26245
- /**
26246
- * @category Attribute
26247
- * @param {string} [color] - Background color (CSS color value)
26248
- */
26249
26761
  color: {
26250
26762
  default: null,
26251
26763
  parseDOM: (element) => element.getAttribute("data-color") || element.style.backgroundColor,
@@ -26273,26 +26785,23 @@ const Highlight = Mark.create({
26273
26785
  * Apply highlight with specified color
26274
26786
  * @category Command
26275
26787
  * @param {string} color - CSS color value
26276
- * @returns {Function} Command
26277
26788
  * @example
26278
- * setHighlight('#FFEB3B')
26279
- * setHighlight('rgba(255, 235, 59, 0.5)')
26789
+ * editor.commands.setHighlight('#FFEB3B')
26790
+ * editor.commands.setHighlight('rgba(255, 235, 59, 0.5)')
26280
26791
  */
26281
26792
  setHighlight: (color) => ({ commands: commands2 }) => commands2.setMark(this.name, { color }),
26282
26793
  /**
26283
26794
  * Remove highlight formatting
26284
26795
  * @category Command
26285
- * @returns {Function} Command
26286
26796
  * @example
26287
- * unsetHighlight()
26797
+ * editor.commands.unsetHighlight()
26288
26798
  */
26289
26799
  unsetHighlight: () => ({ commands: commands2 }) => commands2.unsetMark(this.name),
26290
26800
  /**
26291
26801
  * Toggle highlight formatting
26292
26802
  * @category Command
26293
- * @returns {Function} Command
26294
26803
  * @example
26295
- * toggleHighlight()
26804
+ * editor.commands.toggleHighlight()
26296
26805
  */
26297
26806
  toggleHighlight: () => ({ commands: commands2 }) => commands2.toggleMark(this.name)
26298
26807
  };
@@ -26325,9 +26834,8 @@ const Strike = Mark.create({
26325
26834
  /**
26326
26835
  * Apply strikethrough formatting
26327
26836
  * @category Command
26328
- * @returns {Function} Command
26329
26837
  * @example
26330
- * setStrike()
26838
+ * editor.commands.setStrike()
26331
26839
  */
26332
26840
  setStrike: () => ({ commands: commands2 }) => {
26333
26841
  return commands2.setMark(this.name);
@@ -26335,9 +26843,8 @@ const Strike = Mark.create({
26335
26843
  /**
26336
26844
  * Remove strikethrough formatting
26337
26845
  * @category Command
26338
- * @returns {Function} Command
26339
26846
  * @example
26340
- * unsetStrike()
26847
+ * editor.commands.unsetStrike()
26341
26848
  */
26342
26849
  unsetStrike: () => ({ commands: commands2 }) => {
26343
26850
  return commands2.unsetMark(this.name);
@@ -26345,9 +26852,8 @@ const Strike = Mark.create({
26345
26852
  /**
26346
26853
  * Toggle strikethrough formatting
26347
26854
  * @category Command
26348
- * @returns {Function} Command
26349
26855
  * @example
26350
- * toggleStrike()
26856
+ * editor.commands.toggleStrike()
26351
26857
  */
26352
26858
  toggleStrike: () => ({ commands: commands2 }) => {
26353
26859
  return commands2.toggleMark(this.name);
@@ -26367,11 +26873,6 @@ const Link = Mark.create({
26367
26873
  inclusive: false,
26368
26874
  addOptions() {
26369
26875
  return {
26370
- /**
26371
- * Allowed URL protocols
26372
- * @type {string[]}
26373
- * @default ['http', 'https']
26374
- */
26375
26876
  protocols: ["http", "https"],
26376
26877
  htmlAttributes: {
26377
26878
  target: null,
@@ -26470,16 +26971,10 @@ const Link = Mark.create({
26470
26971
  /**
26471
26972
  * Create or update a link
26472
26973
  * @category Command
26473
- * @param {Object} options - Link configuration
26474
- * @param {string} [options.href] - URL for the link
26475
- * @param {string} [options.text] - Display text (uses selection if omitted)
26476
- * @returns {Function} Command - Creates link with underline
26974
+ * @param {SetLinkOptions} [options] - Link configuration
26477
26975
  * @example
26478
- * // Link selected text
26479
- * setLink({ href: 'https://example.com' })
26480
- *
26481
- * // Link with custom text
26482
- * setLink({
26976
+ * editor.commands.setLink({ href: 'https://example.com' })
26977
+ * editor.commands.setLink({
26483
26978
  * href: 'https://example.com',
26484
26979
  * text: 'Visit Example'
26485
26980
  * })
@@ -26531,9 +27026,8 @@ const Link = Mark.create({
26531
27026
  /**
26532
27027
  * Remove link and associated formatting
26533
27028
  * @category Command
26534
- * @returns {Function} Command - Removes link, underline, and color
26535
27029
  * @example
26536
- * unsetLink()
27030
+ * editor.commands.unsetLink()
26537
27031
  * @note Also removes underline and text color
26538
27032
  */
26539
27033
  unsetLink: () => ({ chain }) => {
@@ -26542,16 +27036,10 @@ const Link = Mark.create({
26542
27036
  /**
26543
27037
  * Toggle link on selection
26544
27038
  * @category Command
26545
- * @param {Object} [options] - Link configuration
26546
- * @param {string} [options.href] - URL for the link
26547
- * @param {string} [options.text] - Display text
26548
- * @returns {Function} Command - Creates link if href provided, removes otherwise
27039
+ * @param {SetLinkOptions} [options] - Link configuration
26549
27040
  * @example
26550
- * // Add link
26551
- * toggleLink({ href: 'https://example.com' })
26552
- *
26553
- * // Remove link
26554
- * toggleLink()
27041
+ * editor.commands.toggleLink({ href: 'https://example.com' })
27042
+ * editor.commands.toggleLink()
26555
27043
  */
26556
27044
  toggleLink: ({ href, text } = {}) => ({ commands: commands2 }) => {
26557
27045
  if (!href) return commands2.unsetLink();
@@ -27438,8 +27926,8 @@ function mergePaddingObject(paddingObject) {
27438
27926
  return Object.assign({}, getFreshSideObject(), paddingObject);
27439
27927
  }
27440
27928
  function expandToHashMap(value, keys2) {
27441
- return keys2.reduce(function(hashMap, key) {
27442
- hashMap[key] = value;
27929
+ return keys2.reduce(function(hashMap, key2) {
27930
+ hashMap[key2] = value;
27443
27931
  return hashMap;
27444
27932
  }, {});
27445
27933
  }
@@ -27895,10 +28383,10 @@ function detectOverflow$1(state, options) {
27895
28383
  var offsetData = state.modifiersData.offset;
27896
28384
  if (elementContext === popper && offsetData) {
27897
28385
  var offset2 = offsetData[placement];
27898
- Object.keys(overflowOffsets).forEach(function(key) {
27899
- var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
27900
- var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x";
27901
- overflowOffsets[key] += offset2[axis] * multiply;
28386
+ Object.keys(overflowOffsets).forEach(function(key2) {
28387
+ var multiply = [right, bottom].indexOf(key2) >= 0 ? 1 : -1;
28388
+ var axis = [top, bottom].indexOf(key2) >= 0 ? "y" : "x";
28389
+ overflowOffsets[key2] += offset2[axis] * multiply;
27902
28390
  });
27903
28391
  }
27904
28392
  return overflowOffsets;
@@ -28345,8 +28833,8 @@ function mergeByName(modifiers2) {
28345
28833
  }) : current;
28346
28834
  return merged2;
28347
28835
  }, {});
28348
- return Object.keys(merged).map(function(key) {
28349
- return merged[key];
28836
+ return Object.keys(merged).map(function(key2) {
28837
+ return merged[key2];
28350
28838
  });
28351
28839
  }
28352
28840
  var DEFAULT_OPTIONS = {
@@ -28503,8 +28991,8 @@ var TOUCH_OPTIONS = {
28503
28991
  var TIPPY_DEFAULT_APPEND_TO = function TIPPY_DEFAULT_APPEND_TO2() {
28504
28992
  return document.body;
28505
28993
  };
28506
- function hasOwnProperty(obj, key) {
28507
- return {}.hasOwnProperty.call(obj, key);
28994
+ function hasOwnProperty(obj, key2) {
28995
+ return {}.hasOwnProperty.call(obj, key2);
28508
28996
  }
28509
28997
  function getValueAtIndexOrReturn(value, index2, defaultValue) {
28510
28998
  if (Array.isArray(value)) {
@@ -28534,8 +29022,8 @@ function debounce(fn2, ms) {
28534
29022
  }
28535
29023
  function removeProperties(obj, keys2) {
28536
29024
  var clone = Object.assign({}, obj);
28537
- keys2.forEach(function(key) {
28538
- delete clone[key];
29025
+ keys2.forEach(function(key2) {
29026
+ delete clone[key2];
28539
29027
  });
28540
29028
  return clone;
28541
29029
  }
@@ -28562,9 +29050,9 @@ function arrayFrom(value) {
28562
29050
  return [].slice.call(value);
28563
29051
  }
28564
29052
  function removeUndefinedProps(obj) {
28565
- return Object.keys(obj).reduce(function(acc, key) {
28566
- if (obj[key] !== void 0) {
28567
- acc[key] = obj[key];
29053
+ return Object.keys(obj).reduce(function(acc, key2) {
29054
+ if (obj[key2] !== void 0) {
29055
+ acc[key2] = obj[key2];
28568
29056
  }
28569
29057
  return acc;
28570
29058
  }, {});
@@ -28816,8 +29304,8 @@ var setDefaultProps = function setDefaultProps2(partialProps) {
28816
29304
  validateProps(partialProps, []);
28817
29305
  }
28818
29306
  var keys2 = Object.keys(partialProps);
28819
- keys2.forEach(function(key) {
28820
- defaultProps[key] = partialProps[key];
29307
+ keys2.forEach(function(key2) {
29308
+ defaultProps[key2] = partialProps[key2];
28821
29309
  });
28822
29310
  };
28823
29311
  function getExtendedPassedProps(passedProps) {
@@ -28836,18 +29324,18 @@ function getDataAttributeProps(reference2, plugins) {
28836
29324
  var propKeys = plugins ? Object.keys(getExtendedPassedProps(Object.assign({}, defaultProps, {
28837
29325
  plugins
28838
29326
  }))) : defaultKeys;
28839
- var props = propKeys.reduce(function(acc, key) {
28840
- var valueAsString = (reference2.getAttribute("data-tippy-" + key) || "").trim();
29327
+ var props = propKeys.reduce(function(acc, key2) {
29328
+ var valueAsString = (reference2.getAttribute("data-tippy-" + key2) || "").trim();
28841
29329
  if (!valueAsString) {
28842
29330
  return acc;
28843
29331
  }
28844
- if (key === "content") {
28845
- acc[key] = valueAsString;
29332
+ if (key2 === "content") {
29333
+ acc[key2] = valueAsString;
28846
29334
  } else {
28847
29335
  try {
28848
- acc[key] = JSON.parse(valueAsString);
29336
+ acc[key2] = JSON.parse(valueAsString);
28849
29337
  } catch (e) {
28850
- acc[key] = valueAsString;
29338
+ acc[key2] = valueAsString;
28851
29339
  }
28852
29340
  }
28853
29341
  return acc;
@@ -29771,8 +30259,8 @@ tippy.setDefaultProps({
29771
30259
  });
29772
30260
  const _export_sfc = (sfc, props) => {
29773
30261
  const target = sfc.__vccOpts || sfc;
29774
- for (const [key, val] of props) {
29775
- target[key] = val;
30262
+ for (const [key2, val] of props) {
30263
+ target[key2] = val;
29776
30264
  }
29777
30265
  return target;
29778
30266
  };
@@ -29868,6 +30356,9 @@ const Mentions = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b
29868
30356
  const popoverPluginKey = new PluginKey("popoverPlugin");
29869
30357
  const PopoverPlugin = Extension.create({
29870
30358
  name: "popoverPlugin",
30359
+ addOptions() {
30360
+ return {};
30361
+ },
29871
30362
  addPmPlugins() {
29872
30363
  const popover = new Plugin({
29873
30364
  key: popoverPluginKey,
@@ -31164,9 +31655,9 @@ const Pagination = Extension.create({
31164
31655
  if (syncMeta && syncMeta.isChangeOrigin || listSyncMeta) {
31165
31656
  return { ...oldState };
31166
31657
  }
31167
- const imagePluginTransaction = tr.getMeta(ImagePlaceholderPluginKey);
31168
- if (imagePluginTransaction) {
31169
- if (imagePluginTransaction.type === "remove") {
31658
+ const imageRegistrationMetaType = getImageRegistrationMetaType(tr);
31659
+ if (imageRegistrationMetaType) {
31660
+ if (imageRegistrationMetaType === "remove") {
31170
31661
  onImageLoad(editor);
31171
31662
  }
31172
31663
  return { ...oldState };
@@ -32095,12 +32586,11 @@ const Search = Extension.create({
32095
32586
  addCommands() {
32096
32587
  return {
32097
32588
  /**
32098
- * Navigates to the first search match
32589
+ * Navigate to the first search match
32099
32590
  * @category Command
32100
- * @returns {Function} - Command function
32101
32591
  * @example
32102
- * goToFirstMatch()
32103
- * @note Scrolls Editor to the first match of called search().
32592
+ * editor.commands.goToFirstMatch()
32593
+ * @note Scrolls editor to the first match from previous search
32104
32594
  */
32105
32595
  goToFirstMatch: () => (
32106
32596
  /** @returns {boolean} */
@@ -32116,13 +32606,13 @@ const Search = Extension.create({
32116
32606
  }
32117
32607
  ),
32118
32608
  /**
32119
- * Searches for the string match in Editor content
32609
+ * Search for string matches in editor content
32120
32610
  * @category Command
32121
32611
  * @param {String|RegExp} patternInput - Search string or pattern
32122
- * @returns {Function} - Command function that returns matches
32123
32612
  * @example
32124
- * search('test string')
32125
- * @note Searches for the test string in the Editor content and returns an array of matches
32613
+ * const matches = editor.commands.search('test string')
32614
+ * const regexMatches = editor.commands.search(/test/i)
32615
+ * @note Returns array of SearchMatch objects with positions and IDs
32126
32616
  */
32127
32617
  search: (patternInput) => (
32128
32618
  /** @returns {SearchMatch[]} */
@@ -32165,14 +32655,13 @@ const Search = Extension.create({
32165
32655
  }
32166
32656
  ),
32167
32657
  /**
32168
- * Navigates to the selected match
32658
+ * Navigate to a specific search match
32169
32659
  * @category Command
32170
- * @param {SearchMatch} match Match at specific index
32171
- * @returns {Function} - Command function
32660
+ * @param {SearchMatch} match - Match object to navigate to
32172
32661
  * @example
32173
- * const searchResult = search('test string')
32174
- * goToSearchResult(searchResult[3])
32175
- * @note Scrolls Editor to the fourth match of called search() and sets selection on it.
32662
+ * const searchResults = editor.commands.search('test string')
32663
+ * editor.commands.goToSearchResult(searchResults[3])
32664
+ * @note Scrolls to match and selects it
32176
32665
  */
32177
32666
  goToSearchResult: (match) => (
32178
32667
  /** @returns {boolean} */
@@ -32434,6 +32923,9 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
32434
32923
  };
32435
32924
  const NodeResizer = Extension.create({
32436
32925
  name: "nodeResizer",
32926
+ addOptions() {
32927
+ return {};
32928
+ },
32437
32929
  addPmPlugins() {
32438
32930
  const isHeadless = this.editor.options.isHeadless;
32439
32931
  const hasDocument = typeof document !== "undefined";
@@ -32525,6 +33017,7 @@ const getStarterExtensions = () => {
32525
33017
  DropCursor,
32526
33018
  Image,
32527
33019
  BookmarkStart,
33020
+ BookmarkEnd,
32528
33021
  Mention,
32529
33022
  Collaboration,
32530
33023
  CollaborationCursor,
@@ -32567,18 +33060,20 @@ export {
32567
33060
  getQuickFormatList as a,
32568
33061
  generateLinkedStyleString as b,
32569
33062
  getFileOpener as c,
32570
- undoDepth as d,
32571
- getStarterExtensions as e,
32572
- getRichTextExtensions as f,
33063
+ checkAndProcessImage as d,
33064
+ uploadAndInsertImage as e,
33065
+ undoDepth as f,
32573
33066
  global as g,
32574
- Extension as h,
32575
- index$1 as i,
32576
- index as j,
32577
- AnnotatorHelpers as k,
32578
- SectionHelpers as l,
32579
- getAllowedImageDimensions as m,
32580
- redoDepth as r,
32581
- startImageUpload as s,
33067
+ redoDepth as h,
33068
+ getStarterExtensions as i,
33069
+ getRichTextExtensions as j,
33070
+ Extension as k,
33071
+ index$1 as l,
33072
+ index as m,
33073
+ AnnotatorHelpers as n,
33074
+ SectionHelpers as o,
33075
+ getAllowedImageDimensions as p,
33076
+ replaceSelectionWithImagePlaceholder as r,
32582
33077
  useHighContrastMode as u,
32583
33078
  yUndoPluginKey as y
32584
33079
  };