superdoc 0.30.0-next.2 → 0.30.0-next.4

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 (172) hide show
  1. package/dist/chunks/{PdfViewer-B_U27-1K.es.js → PdfViewer-DyeZP8Nl.es.js} +2 -2
  2. package/dist/chunks/{PdfViewer-DjMr1y41.cjs → PdfViewer-Sfmu-cdb.cjs} +2 -2
  3. package/dist/chunks/{eventemitter3-BvTILlBo.cjs → eventemitter3-DmHNHvFX.cjs} +1 -1
  4. package/dist/chunks/{eventemitter3-D4gv5QOO.es.js → eventemitter3-hYlnBzSA.es.js} +1 -1
  5. package/dist/chunks/{index-D8F3d1e3.es.js → index-BHHC2mqV.es.js} +6 -6
  6. package/dist/chunks/{index-uO0JG1KW.cjs → index-BuNsREKD.cjs} +6 -6
  7. package/dist/chunks/{index-BJia6SL_-D6cjpcdW.es.js → index-D6-7DIFN-BWm3AMeg.es.js} +1 -1
  8. package/dist/chunks/{index-BJia6SL_-O9_RiF6K.cjs → index-D6-7DIFN-Dhy8SBt-.cjs} +1 -1
  9. package/dist/chunks/{jszip-B0BPx_cv.cjs → jszip-BP2FTbpi.cjs} +7 -7
  10. package/dist/chunks/{jszip-Bhl-Iudl.es.js → jszip-jKrsZoMS.es.js} +7 -7
  11. package/dist/chunks/{super-editor.es-BjEfFiAF.es.js → super-editor.es-Dg85Z65T.es.js} +14326 -15436
  12. package/dist/chunks/{super-editor.es-C0Cv2AzF.cjs → super-editor.es-c6saBc8S.cjs} +14326 -15436
  13. package/dist/chunks/{vue-D1vcEBAQ.es.js → vue-CKmzTNVs.es.js} +2 -2
  14. package/dist/chunks/{vue-BQxRC6G7.cjs → vue-Cwv-wUpm.cjs} +2 -2
  15. package/dist/chunks/xml-js-BSDu25I7.cjs +3 -0
  16. package/dist/chunks/xml-js-CBrRls0f.es.js +2 -0
  17. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  18. package/dist/packages/superdoc/src/core/types/index.d.ts.map +1 -1
  19. package/dist/style.css +0 -22
  20. package/dist/super-editor/ai-writer.es.js +2 -2
  21. package/dist/super-editor/chunks/{converter-DxPmeV-v.js → converter-OJmgERLD.js} +12475 -12504
  22. package/dist/super-editor/chunks/{docx-zipper-BnnW7IuB.js → docx-zipper-DmTCMGub.js} +2 -2
  23. package/dist/super-editor/chunks/{editor-B2jkX1wz.js → editor-BV5Ao3FS.js} +1436 -2503
  24. package/dist/super-editor/chunks/{index-BJia6SL_.js → index-D6-7DIFN.js} +1 -1
  25. package/dist/super-editor/chunks/{toolbar-DFlHgpZd.js → toolbar-s_KEL20H.js} +2 -2
  26. package/dist/super-editor/converter.es.js +2 -2
  27. package/dist/super-editor/docx-zipper.es.js +2 -2
  28. package/dist/super-editor/editor.es.js +3 -3
  29. package/dist/super-editor/file-zipper.es.js +1 -1
  30. package/dist/super-editor/style.css +0 -22
  31. package/dist/super-editor/super-editor/src/components/slash-menu/utils.d.ts.map +1 -1
  32. package/dist/super-editor/super-editor/src/components/toolbar/super-toolbar.d.ts.map +1 -1
  33. package/dist/super-editor/super-editor/src/core/ExtensionService.d.ts.map +1 -1
  34. package/dist/super-editor/super-editor/src/core/InputRule.d.ts.map +1 -1
  35. package/dist/super-editor/super-editor/src/core/commands/__tests__/schemaWithLists.d.ts +1 -1
  36. package/dist/super-editor/super-editor/src/core/commands/changeListLevel.d.ts +15 -0
  37. package/dist/super-editor/super-editor/src/core/commands/changeListLevel.d.ts.map +1 -0
  38. package/dist/super-editor/super-editor/src/core/commands/decreaseListIndent.d.ts +1 -1
  39. package/dist/super-editor/super-editor/src/core/commands/decreaseListIndent.d.ts.map +1 -1
  40. package/dist/super-editor/super-editor/src/core/commands/increaseListIndent.d.ts +2 -1
  41. package/dist/super-editor/super-editor/src/core/commands/increaseListIndent.d.ts.map +1 -1
  42. package/dist/super-editor/super-editor/src/core/commands/index.d.ts +2 -7
  43. package/dist/super-editor/super-editor/src/core/commands/list-helpers/is-list.d.ts +1 -1
  44. package/dist/super-editor/super-editor/src/core/commands/list-helpers/is-list.d.ts.map +1 -1
  45. package/dist/super-editor/super-editor/src/core/commands/list-helpers/list-indent-helpers.d.ts +0 -1
  46. package/dist/super-editor/super-editor/src/core/commands/list-helpers/list-indent-helpers.d.ts.map +1 -1
  47. package/dist/super-editor/super-editor/src/core/commands/removeNumberingProperties.d.ts +4 -0
  48. package/dist/super-editor/super-editor/src/core/commands/removeNumberingProperties.d.ts.map +1 -0
  49. package/dist/super-editor/super-editor/src/core/commands/restartNumbering.d.ts +7 -0
  50. package/dist/super-editor/super-editor/src/core/commands/restartNumbering.d.ts.map +1 -0
  51. package/dist/super-editor/super-editor/src/core/commands/splitBlock.d.ts +2 -1
  52. package/dist/super-editor/super-editor/src/core/commands/splitBlock.d.ts.map +1 -1
  53. package/dist/super-editor/super-editor/src/core/commands/tests/test-schema.d.ts +1 -1
  54. package/dist/super-editor/super-editor/src/core/commands/toggleList.d.ts +6 -56
  55. package/dist/super-editor/super-editor/src/core/commands/toggleList.d.ts.map +1 -1
  56. package/dist/super-editor/super-editor/src/core/extensions/keymap.d.ts.map +1 -1
  57. package/dist/super-editor/super-editor/src/core/helpers/contentProcessor.d.ts +3 -3
  58. package/dist/super-editor/super-editor/src/core/helpers/createNodeFromContent.d.ts +2 -2
  59. package/dist/super-editor/super-editor/src/core/helpers/createNodeFromContent.d.ts.map +1 -1
  60. package/dist/super-editor/super-editor/src/core/helpers/importHtml.d.ts +2 -2
  61. package/dist/super-editor/super-editor/src/core/helpers/importHtml.d.ts.map +1 -1
  62. package/dist/super-editor/super-editor/src/core/helpers/importMarkdown.d.ts +2 -2
  63. package/dist/super-editor/super-editor/src/core/helpers/list-numbering-helpers.d.ts +15 -42
  64. package/dist/super-editor/super-editor/src/core/helpers/list-numbering-helpers.d.ts.map +1 -1
  65. package/dist/super-editor/super-editor/src/core/helpers/pasteListHelpers.d.ts +2 -0
  66. package/dist/super-editor/super-editor/src/core/helpers/pasteListHelpers.d.ts.map +1 -1
  67. package/dist/super-editor/super-editor/src/core/inputRules/docx-paste/docx-paste.d.ts.map +1 -1
  68. package/dist/super-editor/super-editor/src/core/inputRules/html/html-helpers.d.ts +2 -5
  69. package/dist/super-editor/super-editor/src/core/inputRules/html/html-helpers.d.ts.map +1 -1
  70. package/dist/super-editor/super-editor/src/core/super-converter/SuperConverter.d.ts.map +1 -1
  71. package/dist/super-editor/super-editor/src/core/super-converter/exporter.d.ts.map +1 -1
  72. package/dist/super-editor/super-editor/src/core/super-converter/helpers.d.ts +2 -0
  73. package/dist/super-editor/super-editor/src/core/super-converter/helpers.d.ts.map +1 -1
  74. package/dist/super-editor/super-editor/src/core/super-converter/styles.d.ts +6 -4
  75. package/dist/super-editor/super-editor/src/core/super-converter/styles.d.ts.map +1 -1
  76. package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/docxImporter.d.ts +2 -1
  77. package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/docxImporter.d.ts.map +1 -1
  78. package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/listImporter.d.ts +0 -97
  79. package/dist/super-editor/super-editor/src/core/super-converter/v2/importer/listImporter.d.ts.map +1 -1
  80. package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/p/helpers/legacy-handle-paragraph-node.d.ts.map +1 -1
  81. package/dist/super-editor/super-editor/src/extensions/field-annotation/cleanup-commands/cleanUpListsWithAnnotations.d.ts.map +1 -1
  82. package/dist/super-editor/super-editor/src/extensions/field-annotation/cleanup-commands/index.d.ts.map +1 -1
  83. package/dist/super-editor/super-editor/src/extensions/index.d.ts +1 -4
  84. package/dist/super-editor/super-editor/src/extensions/index.d.ts.map +1 -1
  85. package/dist/super-editor/super-editor/src/extensions/linked-styles/helpers.d.ts +1 -1
  86. package/dist/super-editor/super-editor/src/extensions/linked-styles/helpers.d.ts.map +1 -1
  87. package/dist/super-editor/super-editor/src/extensions/paragraph/NumberingManager.d.ts +30 -0
  88. package/dist/super-editor/super-editor/src/extensions/paragraph/NumberingManager.d.ts.map +1 -0
  89. package/dist/super-editor/super-editor/src/extensions/paragraph/ParagraphNodeView.d.ts +37 -0
  90. package/dist/super-editor/super-editor/src/extensions/paragraph/ParagraphNodeView.d.ts.map +1 -0
  91. package/dist/super-editor/super-editor/src/extensions/paragraph/numberingPlugin.d.ts +9 -0
  92. package/dist/super-editor/super-editor/src/extensions/paragraph/numberingPlugin.d.ts.map +1 -0
  93. package/dist/super-editor/super-editor/src/extensions/paragraph/paragraph.d.ts.map +1 -1
  94. package/dist/super-editor/super-editor/src/extensions/run/commands/split-run.d.ts +1 -0
  95. package/dist/super-editor/super-editor/src/extensions/run/commands/split-run.d.ts.map +1 -1
  96. package/dist/super-editor/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts +13 -2
  97. package/dist/super-editor/super-editor/src/extensions/tab/helpers/tabDecorations.d.ts.map +1 -1
  98. package/dist/super-editor/super-editor/src/extensions/text-style/text-style.d.ts.map +1 -1
  99. package/dist/super-editor/super-editor/src/extensions/track-changes/permission-helpers.d.ts.map +1 -1
  100. package/dist/super-editor/super-editor.es.js +75 -40
  101. package/dist/super-editor/toolbar.es.js +2 -2
  102. package/dist/super-editor.cjs +2 -2
  103. package/dist/super-editor.es.js +2 -2
  104. package/dist/superdoc.cjs +2 -2
  105. package/dist/superdoc.es.js +2 -2
  106. package/dist/superdoc.umd.js +14098 -15208
  107. package/dist/superdoc.umd.js.map +1 -1
  108. package/package.json +1 -1
  109. package/dist/chunks/xml-js-cO2Q8Wfu.cjs +0 -3
  110. package/dist/chunks/xml-js-jMPlIVKT.es.js +0 -2
  111. package/dist/images/altText_add.svg +0 -3
  112. package/dist/images/altText_disclaimer.svg +0 -3
  113. package/dist/images/altText_done.svg +0 -3
  114. package/dist/images/altText_spinner.svg +0 -30
  115. package/dist/images/altText_warning.svg +0 -3
  116. package/dist/images/annotation-check.svg +0 -11
  117. package/dist/images/annotation-comment.svg +0 -16
  118. package/dist/images/annotation-help.svg +0 -26
  119. package/dist/images/annotation-insert.svg +0 -10
  120. package/dist/images/annotation-key.svg +0 -11
  121. package/dist/images/annotation-newparagraph.svg +0 -11
  122. package/dist/images/annotation-noicon.svg +0 -7
  123. package/dist/images/annotation-note.svg +0 -42
  124. package/dist/images/annotation-paperclip.svg +0 -6
  125. package/dist/images/annotation-paragraph.svg +0 -16
  126. package/dist/images/annotation-pushpin.svg +0 -7
  127. package/dist/images/cursor-editorFreeHighlight.svg +0 -6
  128. package/dist/images/cursor-editorFreeText.svg +0 -3
  129. package/dist/images/cursor-editorInk.svg +0 -4
  130. package/dist/images/cursor-editorTextHighlight.svg +0 -8
  131. package/dist/images/editor-toolbar-delete.svg +0 -5
  132. package/dist/images/loading-icon.gif +0 -0
  133. package/dist/images/messageBar_closingButton.svg +0 -3
  134. package/dist/images/messageBar_warning.svg +0 -3
  135. package/dist/images/toolbarButton-editorHighlight.svg +0 -6
  136. package/dist/images/toolbarButton-menuArrow.svg +0 -3
  137. package/dist/super-editor/super-editor/src/core/commands/backspaceNextToList.d.ts +0 -6
  138. package/dist/super-editor/super-editor/src/core/commands/backspaceNextToList.d.ts.map +0 -1
  139. package/dist/super-editor/super-editor/src/core/commands/deleteListItem.d.ts +0 -2
  140. package/dist/super-editor/super-editor/src/core/commands/deleteListItem.d.ts.map +0 -1
  141. package/dist/super-editor/super-editor/src/core/commands/deleteNextToList.d.ts +0 -15
  142. package/dist/super-editor/super-editor/src/core/commands/deleteNextToList.d.ts.map +0 -1
  143. package/dist/super-editor/super-editor/src/core/commands/liftListItem.d.ts +0 -5
  144. package/dist/super-editor/super-editor/src/core/commands/liftListItem.d.ts.map +0 -1
  145. package/dist/super-editor/super-editor/src/core/commands/sinkListItem.d.ts +0 -5
  146. package/dist/super-editor/super-editor/src/core/commands/sinkListItem.d.ts.map +0 -1
  147. package/dist/super-editor/super-editor/src/core/commands/splitListItem.d.ts +0 -2
  148. package/dist/super-editor/super-editor/src/core/commands/splitListItem.d.ts.map +0 -1
  149. package/dist/super-editor/super-editor/src/core/commands/wrapInList.d.ts +0 -5
  150. package/dist/super-editor/super-editor/src/core/commands/wrapInList.d.ts.map +0 -1
  151. package/dist/super-editor/super-editor/src/extensions/bullet-list/bullet-list.d.ts +0 -15
  152. package/dist/super-editor/super-editor/src/extensions/bullet-list/bullet-list.d.ts.map +0 -1
  153. package/dist/super-editor/super-editor/src/extensions/bullet-list/index.d.ts +0 -2
  154. package/dist/super-editor/super-editor/src/extensions/bullet-list/index.d.ts.map +0 -1
  155. package/dist/super-editor/super-editor/src/extensions/list-item/ListItemNodeView.d.ts +0 -43
  156. package/dist/super-editor/super-editor/src/extensions/list-item/ListItemNodeView.d.ts.map +0 -1
  157. package/dist/super-editor/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts +0 -68
  158. package/dist/super-editor/super-editor/src/extensions/list-item/helpers/listItemTypography.d.ts.map +0 -1
  159. package/dist/super-editor/super-editor/src/extensions/list-item/helpers/styledListMarkerPlugin.d.ts +0 -13
  160. package/dist/super-editor/super-editor/src/extensions/list-item/helpers/styledListMarkerPlugin.d.ts.map +0 -1
  161. package/dist/super-editor/super-editor/src/extensions/list-item/index.d.ts +0 -2
  162. package/dist/super-editor/super-editor/src/extensions/list-item/index.d.ts.map +0 -1
  163. package/dist/super-editor/super-editor/src/extensions/list-item/list-item.d.ts +0 -51
  164. package/dist/super-editor/super-editor/src/extensions/list-item/list-item.d.ts.map +0 -1
  165. package/dist/super-editor/super-editor/src/extensions/ordered-list/helpers/orderedListMarkerPlugin.d.ts +0 -3
  166. package/dist/super-editor/super-editor/src/extensions/ordered-list/helpers/orderedListMarkerPlugin.d.ts.map +0 -1
  167. package/dist/super-editor/super-editor/src/extensions/ordered-list/helpers/orderedListSyncPlugin.d.ts +0 -6
  168. package/dist/super-editor/super-editor/src/extensions/ordered-list/helpers/orderedListSyncPlugin.d.ts.map +0 -1
  169. package/dist/super-editor/super-editor/src/extensions/ordered-list/index.d.ts +0 -2
  170. package/dist/super-editor/super-editor/src/extensions/ordered-list/index.d.ts.map +0 -1
  171. package/dist/super-editor/super-editor/src/extensions/ordered-list/ordered-list.d.ts +0 -38
  172. package/dist/super-editor/super-editor/src/extensions/ordered-list/ordered-list.d.ts.map +0 -1
@@ -9,11 +9,11 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
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, registerCopyHandler_fn, insertNewFileData_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_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, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ListItemNodeView_instances, init_fn3, applyIndentStyling_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_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, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_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, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, updateHTMLAttributes_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_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 updateDOMAttributes, ah as findChildren$5, ai as htmlHandler, aj as generateRandomSigned32BitIntStrId, ak as InputRule, al as kebabCase, am as twipsToPixels, an as halfPointToPixels, ao as findParentNodeClosestToPos, ap as docxNumberingHelpers, aq as getListItemStyleDefinitions, ar as parseIndentElement, as as combineIndents, at as eighthPointsToPixels, au as linesToTwips, av as PIXELS_PER_INCH, aw as SelectionRange, ax as Transform, ay as isInTable$1, az as generateDocxRandomId, aA as insertNewRelationship, aB as inchesToPixels } from "./converter-DxPmeV-v.js";
16
- import { D as DocxZipper } from "./docx-zipper-BnnW7IuB.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 htmlHandler, E as ReplaceStep, L as ListHelpers, G as updateNumberingProperties, H as changeListLevel, I as findParentNode, J as isList, K as isMacOS, O as isIOS, Q as getSchemaTypeByName, U as inputRulesPlugin, V as TrackDeleteMarkName, W as TrackInsertMarkName, X as v4, Y as TrackFormatMarkName, Z as comments_module_events, _ as findMark, $ as objectIncludes, a0 as AddMarkStep, a1 as RemoveMarkStep, a2 as twipsToLines, a3 as pixelsToTwips, a4 as helpers, a5 as posToDOMRect, a6 as CommandService, a7 as SuperConverter, a8 as createDocument, a9 as createDocFromMarkdown, aa as createDocFromHTML, ab as EditorState, ac as hasSomeParentWithClass, ad as isActive, ae as unflattenListsInHtml, af as parseSizeUnit, ag as minMax, ah as getLineHeightValueString, ai as updateDOMAttributes, aj as findChildren$5, ak as generateRandomSigned32BitIntStrId, al as kebabCase, am as twipsToPixels, an as halfPointToPixels, ao as getUnderlineCssString, ap as findParentNodeClosestToPos, aq as resolveRunProperties, ar as encodeCSSFromRPr, as as docxNumberingHelpers, at as InputRule, au as resolveParagraphProperties, av as eighthPointsToPixels, aw as linesToTwips, ax as PIXELS_PER_INCH, ay as SelectionRange, az as Transform, aA as isInTable$1, aB as generateDocxRandomId, aC as insertNewRelationship, aD as inchesToPixels } from "./converter-OJmgERLD.js";
16
+ import { D as DocxZipper } from "./docx-zipper-DmTCMGub.js";
17
17
  import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
@@ -8251,12 +8251,15 @@ const ensureMarks = (state, splittableMarks) => {
8251
8251
  state.tr.ensureMarks(filtered);
8252
8252
  }
8253
8253
  };
8254
- const splitBlock$1 = ({ keepMarks = true } = {}) => (props) => {
8254
+ const splitBlock$1 = ({ keepMarks = true, attrsToRemoveOverride = [] } = {}) => (props) => {
8255
8255
  const { tr, state, dispatch, editor } = props;
8256
8256
  const { selection, doc: doc2 } = tr;
8257
8257
  const { $from, $to } = selection;
8258
8258
  const extensionAttrs = editor.extensionService.attributes;
8259
- const newAttrs = Attribute.getSplittedAttributes(extensionAttrs, $from.node().type.name, $from.node().attrs);
8259
+ let newAttrs = Attribute.getSplittedAttributes(extensionAttrs, $from.node().type.name, $from.node().attrs);
8260
+ if (attrsToRemoveOverride.length > 0) {
8261
+ newAttrs = deleteAttributes(newAttrs, attrsToRemoveOverride);
8262
+ }
8260
8263
  if (selection instanceof NodeSelection && selection.node.isBlock) {
8261
8264
  if (!$from.parentOffset || !canSplit(doc2, $from.pos)) return false;
8262
8265
  if (dispatch) {
@@ -8291,6 +8294,23 @@ const splitBlock$1 = ({ keepMarks = true } = {}) => (props) => {
8291
8294
  }
8292
8295
  return true;
8293
8296
  };
8297
+ function deleteAttributes(attrs, attrsToRemove) {
8298
+ const newAttrs = { ...attrs };
8299
+ attrsToRemove.forEach((attrName) => {
8300
+ const parts = attrName.split(".");
8301
+ if (parts.length === 1) {
8302
+ delete newAttrs[attrName];
8303
+ } else {
8304
+ let current = newAttrs;
8305
+ for (let i = 0; i < parts.length - 1; i++) {
8306
+ if (current[parts[i]] == null) return;
8307
+ current = current[parts[i]];
8308
+ }
8309
+ delete current[parts[parts.length - 1]];
8310
+ }
8311
+ });
8312
+ return newAttrs;
8313
+ }
8294
8314
  const deleteSelection$1 = (state, dispatch) => {
8295
8315
  if (state.selection.empty)
8296
8316
  return false;
@@ -9111,7 +9131,7 @@ const selectNodeBackward = () => ({ state, dispatch }) => {
9111
9131
  const selectNodeForward = () => ({ state, dispatch }) => selectNodeForward$1(state, dispatch);
9112
9132
  const selectTextblockStart = () => ({ state, dispatch }) => selectTextblockStart$1(state, dispatch);
9113
9133
  const selectTextblockEnd = () => ({ state, dispatch }) => selectTextblockEnd$1(state, dispatch);
9114
- const insertContent = (value, options = {}) => ({ tr, state, commands: commands2, editor }) => {
9134
+ const insertContent = (value, options = {}) => ({ tr, commands: commands2, editor }) => {
9115
9135
  if (options.contentType) {
9116
9136
  const validTypes = ["html", "markdown", "text", "schema"];
9117
9137
  if (!validTypes.includes(options.contentType)) {
@@ -9122,7 +9142,7 @@ const insertContent = (value, options = {}) => ({ tr, state, commands: commands2
9122
9142
  const processedDoc = processContent({
9123
9143
  content: value,
9124
9144
  type: options.contentType,
9125
- schema: state.schema
9145
+ editor
9126
9146
  });
9127
9147
  const jsonContent = processedDoc.toJSON();
9128
9148
  const ok = commands2.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, jsonContent, options);
@@ -9149,12 +9169,13 @@ const removeWhitespaces = (node) => {
9149
9169
  }
9150
9170
  return node;
9151
9171
  };
9152
- function elementFromString(value) {
9172
+ function elementFromString(value, editor) {
9153
9173
  const wrappedValue = `<body>${value}</body>`;
9154
- const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
9174
+ const html = htmlHandler(wrappedValue, editor);
9155
9175
  return removeWhitespaces(html);
9156
9176
  }
9157
- function createNodeFromContent(content, schema, options) {
9177
+ function createNodeFromContent(content, editor, options) {
9178
+ const schema = editor.schema;
9158
9179
  options = {
9159
9180
  slice: true,
9160
9181
  parseOptions: {},
@@ -9178,7 +9199,7 @@ function createNodeFromContent(content, schema, options) {
9178
9199
  throw new Error("[super-editor error]: Invalid JSON content", { cause: error });
9179
9200
  }
9180
9201
  console.warn("[super-editor warn]: Invalid content.", "Passed value:", content, "Error:", error);
9181
- return createNodeFromContent("", schema, options);
9202
+ return createNodeFromContent("", editor, options);
9182
9203
  }
9183
9204
  }
9184
9205
  if (isTextContent) {
@@ -9208,9 +9229,9 @@ function createNodeFromContent(content, schema, options) {
9208
9229
  })
9209
9230
  });
9210
9231
  if (options.slice) {
9211
- DOMParser$1.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
9232
+ DOMParser$1.fromSchema(contentCheckSchema).parseSlice(elementFromString(content, editor), options.parseOptions);
9212
9233
  } else {
9213
- DOMParser$1.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
9234
+ DOMParser$1.fromSchema(contentCheckSchema).parse(elementFromString(content, editor), options.parseOptions);
9214
9235
  }
9215
9236
  if (options.errorOnInvalidContent && hasInvalidContent) {
9216
9237
  throw new Error("[super-editor error]: Invalid HTML content", {
@@ -9220,11 +9241,11 @@ function createNodeFromContent(content, schema, options) {
9220
9241
  }
9221
9242
  const parser = DOMParser$1.fromSchema(schema);
9222
9243
  if (options.slice) {
9223
- return parser.parseSlice(elementFromString(content), options.parseOptions).content;
9244
+ return parser.parseSlice(elementFromString(content, editor), options.parseOptions).content;
9224
9245
  }
9225
- return parser.parse(elementFromString(content), options.parseOptions);
9246
+ return parser.parse(elementFromString(content, editor), options.parseOptions);
9226
9247
  }
9227
- return createNodeFromContent("", schema, options);
9248
+ return createNodeFromContent("", editor, options);
9228
9249
  }
9229
9250
  function selectionToInsertionEnd(tr, startLen, bias) {
9230
9251
  const last = tr.steps.length - 1;
@@ -9260,7 +9281,7 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
9260
9281
  };
9261
9282
  let content;
9262
9283
  try {
9263
- content = createNodeFromContent(value, editor.schema, {
9284
+ content = createNodeFromContent(value, editor, {
9264
9285
  parseOptions: {
9265
9286
  preserveWhitespace: "full",
9266
9287
  ...options.parseOptions
@@ -9347,539 +9368,112 @@ const undoInputRule = () => ({ state, dispatch }) => {
9347
9368
  }
9348
9369
  return false;
9349
9370
  };
9350
- function wrapInList$1(listType, attrs = null) {
9351
- return function(state, dispatch) {
9352
- let { $from, $to } = state.selection;
9353
- let range = $from.blockRange($to);
9354
- if (!range)
9355
- return false;
9356
- let tr = dispatch ? state.tr : null;
9357
- if (!wrapRangeInList(tr, range, listType, attrs))
9358
- return false;
9359
- if (dispatch)
9360
- dispatch(tr.scrollIntoView());
9361
- return true;
9362
- };
9363
- }
9364
- function wrapRangeInList(tr, range, listType, attrs = null) {
9365
- let doJoin = false, outerRange = range, doc2 = range.$from.doc;
9366
- if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) {
9367
- if (range.$from.index(range.depth - 1) == 0)
9368
- return false;
9369
- let $insert = doc2.resolve(range.start - 2);
9370
- outerRange = new NodeRange($insert, $insert, range.depth);
9371
- if (range.endIndex < range.parent.childCount)
9372
- range = new NodeRange(range.$from, doc2.resolve(range.$to.end(range.depth)), range.depth);
9373
- doJoin = true;
9374
- }
9375
- let wrap = findWrapping(outerRange, listType, attrs, range);
9376
- if (!wrap)
9377
- return false;
9378
- if (tr)
9379
- doWrapInList(tr, range, wrap, doJoin, listType);
9380
- return true;
9381
- }
9382
- function doWrapInList(tr, range, wrappers, joinBefore, listType) {
9383
- let content = Fragment.empty;
9384
- for (let i = wrappers.length - 1; i >= 0; i--)
9385
- content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content));
9386
- tr.step(new ReplaceAroundStep$1(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true));
9387
- let found = 0;
9388
- for (let i = 0; i < wrappers.length; i++)
9389
- if (wrappers[i].type == listType)
9390
- found = i + 1;
9391
- let splitDepth = wrappers.length - found;
9392
- let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent;
9393
- for (let i = range.startIndex, e = range.endIndex, first2 = true; i < e; i++, first2 = false) {
9394
- if (!first2 && canSplit(tr.doc, splitPos, splitDepth)) {
9395
- tr.split(splitPos, splitDepth);
9396
- splitPos += 2 * splitDepth;
9397
- }
9398
- splitPos += parent.child(i).nodeSize;
9399
- }
9400
- return tr;
9401
- }
9402
- function liftListItem$1(itemType) {
9403
- return function(state, dispatch) {
9404
- let { $from, $to } = state.selection;
9405
- let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
9406
- if (!range)
9407
- return false;
9408
- if (!dispatch)
9409
- return true;
9410
- if ($from.node(range.depth - 1).type == itemType)
9411
- return liftToOuterList(state, dispatch, itemType, range);
9412
- else
9413
- return liftOutOfList(state, dispatch, range);
9414
- };
9415
- }
9416
- function liftToOuterList(state, dispatch, itemType, range) {
9417
- let tr = state.tr, end2 = range.end, endOfList = range.$to.end(range.depth);
9418
- if (end2 < endOfList) {
9419
- tr.step(new ReplaceAroundStep$1(end2 - 1, endOfList, end2, endOfList, new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true));
9420
- range = new NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth);
9421
- }
9422
- const target = liftTarget(range);
9423
- if (target == null)
9371
+ const toggleList = (listType) => ({ editor, state, tr, dispatch }) => {
9372
+ let predicate;
9373
+ if (listType === "orderedList") {
9374
+ predicate = (n) => n.attrs.numberingProperties && n.attrs.listRendering && n.attrs.listRendering.numberingType !== "bullet";
9375
+ } else if (listType === "bulletList") {
9376
+ predicate = (n) => n.attrs.numberingProperties && n.attrs.listRendering && n.attrs.listRendering.numberingType === "bullet";
9377
+ } else {
9424
9378
  return false;
9425
- tr.lift(range, target);
9426
- let $after = tr.doc.resolve(tr.mapping.map(end2, -1) - 1);
9427
- if (canJoin(tr.doc, $after.pos) && $after.nodeBefore.type == $after.nodeAfter.type)
9428
- tr.join($after.pos);
9429
- dispatch(tr.scrollIntoView());
9430
- return true;
9431
- }
9432
- function liftOutOfList(state, dispatch, range) {
9433
- let tr = state.tr, list = range.parent;
9434
- for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) {
9435
- pos -= list.child(i).nodeSize;
9436
- tr.delete(pos - 1, pos + 1);
9437
9379
  }
9438
- let $start = tr.doc.resolve(range.start), item = $start.nodeAfter;
9439
- if (tr.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize)
9440
- return false;
9441
- let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount;
9442
- let parent = $start.node(-1), indexBefore = $start.index(-1);
9443
- if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment.empty : Fragment.from(list))))
9444
- return false;
9445
- let start2 = $start.pos, end2 = start2 + item.nodeSize;
9446
- tr.step(new ReplaceAroundStep$1(start2 - (atStart ? 1 : 0), end2 + (atEnd ? 1 : 0), start2 + 1, end2 - 1, new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))).append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1));
9447
- dispatch(tr.scrollIntoView());
9448
- return true;
9449
- }
9450
- function sinkListItem$1(itemType) {
9451
- return function(state, dispatch) {
9452
- let { $from, $to } = state.selection;
9453
- let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
9454
- if (!range)
9455
- return false;
9456
- let startIndex = range.startIndex;
9457
- if (startIndex == 0)
9458
- return false;
9459
- let parent = range.parent, nodeBefore = parent.child(startIndex - 1);
9460
- if (nodeBefore.type != itemType)
9380
+ const { selection } = state;
9381
+ const { from: from2, to } = selection;
9382
+ let firstListNode = null;
9383
+ let hasNonListParagraphs = false;
9384
+ let paragraphsInSelection = [];
9385
+ state.doc.nodesBetween(from2, to, (node, pos) => {
9386
+ if (node.type.name === "paragraph") {
9387
+ paragraphsInSelection.push({ node, pos });
9388
+ if (!firstListNode && predicate(node)) {
9389
+ firstListNode = node;
9390
+ } else if (!predicate(node)) {
9391
+ hasNonListParagraphs = true;
9392
+ }
9461
9393
  return false;
9462
- if (dispatch) {
9463
- let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type;
9464
- let inner = Fragment.from(nestedBefore ? itemType.create() : null);
9465
- let slice2 = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0);
9466
- let before = range.start, after = range.end;
9467
- dispatch(state.tr.step(new ReplaceAroundStep$1(before - (nestedBefore ? 3 : 1), after, before, after, slice2, 1, true)).scrollIntoView());
9468
9394
  }
9469
9395
  return true;
9470
- };
9471
- }
9472
- const wrapInList = (typeOrName, attrs = {}) => ({ state, dispatch }) => {
9473
- const type = getNodeType(typeOrName, state.schema);
9474
- return wrapInList$1(type, attrs)(state, dispatch);
9475
- };
9476
- function nearestListAt($pos, OrderedType, BulletType) {
9477
- for (let d2 = $pos.depth; d2 >= 0; d2--) {
9478
- const node = $pos.node(d2);
9479
- if (node.type === OrderedType || node.type === BulletType) {
9480
- return { node, pos: $pos.before(d2), depth: d2 };
9481
- }
9482
- }
9483
- return null;
9484
- }
9485
- function getEffectiveListKind(node) {
9486
- if (!node) return null;
9487
- const typeName = node.type?.name;
9488
- const style = node.attrs?.["list-style-type"];
9489
- if (typeName === "bulletList") return "bullet";
9490
- if (typeName === "orderedList") {
9491
- if (style === "bullet") return "bullet";
9492
- const firstLI = node.firstChild;
9493
- const liFmt = firstLI?.attrs?.listNumberingType;
9494
- if (liFmt === "bullet") return "bullet";
9495
- return "ordered";
9496
- }
9497
- return null;
9498
- }
9499
- function collectIntersectingTopLists({ doc: doc2, selection, OrderedType, BulletType }) {
9500
- const { from: from2, to, $from, $to } = selection;
9501
- const hit = /* @__PURE__ */ new Map();
9502
- const startList = nearestListAt($from, OrderedType, BulletType);
9503
- if (startList) hit.set(startList.pos, startList);
9504
- const endList = nearestListAt($to, OrderedType, BulletType);
9505
- if (endList) hit.set(endList.pos, endList);
9506
- const a = $from.nodeAfter;
9507
- if (a && (a.type === OrderedType || a.type === BulletType)) {
9508
- hit.set($from.pos, { node: a, pos: $from.pos, depth: null });
9509
- }
9510
- const b = $to.nodeBefore;
9511
- if (b && (b.type === OrderedType || b.type === BulletType)) {
9512
- const posB = $to.pos - b.nodeSize;
9513
- hit.set(posB, { node: b, pos: posB, depth: null });
9514
- }
9515
- doc2.nodesBetween(from2, to, (node, pos, parent) => {
9516
- const isList2 = node.type === OrderedType || node.type === BulletType;
9517
- if (!isList2) return true;
9518
- const parentIsList = parent && (parent.type === OrderedType || parent.type === BulletType);
9519
- if (!parentIsList) hit.set(pos, { node, pos, depth: null });
9520
- return false;
9521
9396
  });
9522
- return Array.from(hit.values()).sort((a2, b2) => b2.pos - a2.pos);
9523
- }
9524
- function computeListLevels(liNodes) {
9525
- const levelsOut = [];
9526
- const counters = [];
9527
- for (let i = 0; i < liNodes.length; i++) {
9528
- const lvl = Math.max(0, Number(liNodes[i]?.attrs?.level ?? 0));
9529
- while (counters.length <= lvl) counters.push(0);
9530
- counters.splice(lvl + 1);
9531
- counters[lvl] = (counters[lvl] ?? 0) + 1;
9532
- levelsOut.push(counters.slice(0, lvl + 1));
9533
- }
9534
- return levelsOut;
9535
- }
9536
- function rebuildListNodeWithNewNum({ oldList, toType, editor, schema, fixedNumId }) {
9537
- const OrderedType = schema.nodes.orderedList;
9538
- const isOrdered = toType === OrderedType;
9539
- const numId = fixedNumId ?? ListHelpers.getNewListId(editor);
9540
- if (fixedNumId == null) {
9541
- ListHelpers.generateNewListDefinition?.({ numId: Number(numId), listType: toType, editor });
9542
- }
9543
- const liNodes = [];
9544
- for (let i = 0; i < oldList.childCount; i++) {
9545
- const li = oldList.child(i);
9546
- if (li?.type?.name === "listItem") liNodes.push(li);
9547
- }
9548
- const computedLevels = isOrdered ? computeListLevels(liNodes) : [];
9549
- const items = [];
9550
- for (let i = 0; i < liNodes.length; i++) {
9551
- const li = liNodes[i];
9552
- const level = Math.max(0, Number(li.attrs?.level ?? 0));
9553
- const listLevel = isOrdered ? computedLevels[i] ?? [i + 1] : Array.isArray(li.attrs?.listLevel) ? li.attrs.listLevel : [level + 1];
9554
- const details = ListHelpers.getListDefinitionDetails?.({ numId: Number(numId), level, listType: toType, editor }) || {};
9555
- const effectiveFmt = isOrdered ? details.numFmt || "decimal" : details.numFmt || "bullet";
9556
- const effectiveLvlText = isOrdered ? details.lvlText || "%1." : details.lvlText || "•";
9557
- const baseAttrs = li.attrs || {};
9558
- const itemAttrs = {
9559
- ...baseAttrs,
9560
- level,
9561
- listLevel,
9562
- numId,
9563
- numPrType: "inline",
9564
- listNumberingType: effectiveFmt,
9565
- lvlText: effectiveLvlText
9566
- };
9567
- const contentJSON = li.content && li.content.size > 0 ? li.content.toJSON() : [{ type: "paragraph", content: [] }];
9568
- items.push({
9569
- type: "listItem",
9570
- attrs: itemAttrs,
9571
- content: contentJSON
9572
- });
9573
- }
9574
- const containerJSON = {
9575
- type: isOrdered ? "orderedList" : "bulletList",
9576
- attrs: {
9577
- listId: numId,
9578
- "list-style-type": isOrdered ? items[0]?.attrs?.listNumberingType ?? "decimal" : items[0]?.attrs?.listNumberingType ?? "bullet",
9579
- ...isOrdered ? { order: 1 } : {}
9580
- },
9581
- content: items
9582
- };
9583
- return editor.schema.nodeFromJSON(containerJSON);
9584
- }
9585
- function buildListContainersFromParagraphs({ paragraphs, targetKind, editor, schema }) {
9586
- const OrderedType = schema.nodes.orderedList;
9587
- const BulletType = schema.nodes.bulletList;
9588
- const toType = targetKind === "ordered" ? OrderedType : BulletType;
9589
- const numId = ListHelpers.getNewListId(editor);
9590
- ListHelpers.generateNewListDefinition?.({ numId, listType: toType, editor });
9591
- const isOrdered = targetKind === "ordered";
9592
- const containers = [];
9593
- for (let i = 0; i < paragraphs.length; i++) {
9594
- const { node } = paragraphs[i];
9595
- const level = 0;
9596
- const listLevel = [1];
9597
- const numFmt = isOrdered ? "decimal" : "bullet";
9598
- const lvlText = isOrdered ? "%1." : "•";
9599
- const itemJSON = ListHelpers.createListItemNodeJSON({
9600
- level,
9601
- listLevel,
9602
- numId,
9603
- numFmt,
9604
- lvlText,
9605
- contentNode: node.toJSON()
9606
- // preserve runs
9607
- });
9608
- itemJSON.attrs = {
9609
- ...itemJSON.attrs || {},
9610
- level,
9611
- listLevel,
9612
- numId,
9613
- numPrType: "inline",
9614
- listNumberingType: numFmt,
9615
- lvlText
9616
- };
9617
- const containerJSON = {
9618
- type: isOrdered ? "orderedList" : "bulletList",
9619
- attrs: {
9620
- listId: numId,
9621
- "list-style-type": isOrdered ? "decimal" : "bullet",
9622
- ...isOrdered ? { order: 1 } : {}
9623
- },
9624
- content: [itemJSON]
9625
- };
9626
- containers.push(editor.schema.nodeFromJSON(containerJSON));
9627
- }
9628
- return containers;
9629
- }
9630
- function setMappedSelectionSpan(tr, fromBefore, toBefore) {
9631
- const mappedFrom = tr.mapping.map(fromBefore, -1);
9632
- const mappedTo = tr.mapping.map(toBefore, 1);
9633
- const $from = tr.doc.resolve(Math.max(1, Math.min(mappedFrom, tr.doc.content.size)));
9634
- const $to = tr.doc.resolve(Math.max(1, Math.min(mappedTo, tr.doc.content.size)));
9635
- tr.setSelection(TextSelection.between($from, $to));
9636
- }
9637
- function setCaretInsideFirstTextblockOfNodeAt(tr, containerPos) {
9638
- const node = tr.doc.nodeAt(containerPos);
9639
- if (!node) return;
9640
- let found = null;
9641
- node.descendants((n, p) => {
9642
- if (n.isTextblock) {
9643
- found = containerPos + p + 2;
9644
- return false;
9397
+ if (!firstListNode && from2 > 0) {
9398
+ const $from = state.doc.resolve(from2);
9399
+ const parentIndex = $from.index(-1);
9400
+ if (parentIndex > 0) {
9401
+ const beforeNode = $from.node(-1).child(parentIndex - 1);
9402
+ if (beforeNode && beforeNode.type.name === "paragraph" && predicate(beforeNode)) {
9403
+ firstListNode = beforeNode;
9404
+ }
9645
9405
  }
9646
- return true;
9647
- });
9648
- if (found != null) {
9649
- tr.setSelection(TextSelection.create(tr.doc, found, found));
9650
- } else {
9651
- const fallback = Math.min(tr.doc.content.size, Math.max(1, containerPos + 1));
9652
- tr.setSelection(TextSelection.create(tr.doc, fallback, fallback));
9653
9406
  }
9654
- }
9655
- const toggleList = (listType) => ({ editor, state, tr, dispatch }) => {
9656
- const { selection, doc: doc2 } = state;
9657
- const OrderedType = editor.schema.nodes.orderedList;
9658
- const BulletType = editor.schema.nodes.bulletList;
9659
- const TargetType = typeof listType === "string" ? editor.schema.nodes[listType] : listType;
9660
- const targetKind = TargetType === OrderedType ? "ordered" : "bullet";
9661
- const isListNode = (n) => !!n && (n.type === OrderedType || n.type === BulletType);
9662
- let near = nearestListAt(selection.$from, OrderedType, BulletType);
9663
- if (!near) {
9664
- const after = selection.$from.nodeAfter;
9665
- if (isListNode(after)) {
9666
- near = { node: after, pos: selection.$from.pos, depth: selection.$from.depth + 1 };
9407
+ let mode = null;
9408
+ let sharedNumberingProperties = null;
9409
+ if (firstListNode) {
9410
+ if (!hasNonListParagraphs) {
9411
+ mode = "remove";
9667
9412
  } else {
9668
- const before = selection.$from.nodeBefore;
9669
- if (isListNode(before)) {
9670
- const pos2 = selection.$from.pos - before.nodeSize;
9671
- near = { node: before, pos: pos2, depth: selection.$from.depth + 1 };
9672
- }
9673
- }
9674
- }
9675
- const nearKind = near ? getEffectiveListKind(near.node) : null;
9676
- if (near) {
9677
- const isSameAsTarget = nearKind === targetKind;
9678
- if (isSameAsTarget) {
9679
- const candidateLists = collectIntersectingTopLists({ doc: doc2, selection, OrderedType, BulletType });
9680
- let listsToUnwrap = candidateLists.filter(({ node }) => getEffectiveListKind(node) === targetKind);
9681
- if (listsToUnwrap.length === 0 && getEffectiveListKind(near.node) === targetKind) {
9682
- listsToUnwrap = [{ node: near.node, pos: near.pos, depth: near.depth ?? null }];
9683
- }
9684
- if (listsToUnwrap.length === 0) return false;
9685
- let spanFromBefore2 = listsToUnwrap[0].pos;
9686
- let spanToBefore2 = listsToUnwrap[0].pos + listsToUnwrap[0].node.nodeSize;
9687
- for (let i = 1; i < listsToUnwrap.length; i++) {
9688
- const { node, pos: pos2 } = listsToUnwrap[i];
9689
- spanFromBefore2 = Math.min(spanFromBefore2, pos2);
9690
- spanToBefore2 = Math.max(spanToBefore2, pos2 + node.nodeSize);
9691
- }
9692
- const ParagraphType = editor.schema.nodes.paragraph;
9693
- listsToUnwrap.sort((a, b) => b.pos - a.pos);
9694
- for (const { node, pos: pos2 } of listsToUnwrap) {
9695
- const mappedFrom = tr.mapping.map(pos2, -1);
9696
- const mappedTo = tr.mapping.map(pos2 + node.nodeSize, 1);
9697
- const currentListNode = tr.doc.nodeAt(mappedFrom);
9698
- const sourceListNode = currentListNode && (currentListNode.type === OrderedType || currentListNode.type === BulletType) ? currentListNode : node;
9699
- const paragraphs = [];
9700
- for (let i = 0; i < sourceListNode.childCount; i++) {
9701
- const li = sourceListNode.child(i);
9702
- if (li.type !== editor.schema.nodes.listItem) continue;
9703
- const firstChild = li.firstChild;
9704
- paragraphs.push(firstChild || ParagraphType.create());
9705
- }
9706
- if (paragraphs.length === 0) {
9707
- paragraphs.push(ParagraphType.create());
9708
- }
9709
- const replacement = paragraphs.length === 1 ? paragraphs[0] : Fragment.from(paragraphs);
9710
- tr.replaceWith(mappedFrom, mappedTo, replacement);
9711
- }
9712
- setMappedSelectionSpan(tr, spanFromBefore2, spanToBefore2);
9713
- if (dispatch) dispatch(tr);
9714
- return true;
9715
- }
9716
- let touchedLists = collectIntersectingTopLists({ doc: doc2, selection, OrderedType, BulletType });
9717
- if (touchedLists.length === 0) {
9718
- touchedLists = [{ node: near.node, pos: near.pos, depth: near.depth }];
9719
- }
9720
- let spanFromBefore = Infinity;
9721
- let spanToBefore = -Infinity;
9722
- for (const { node, pos: pos2 } of touchedLists) {
9723
- spanFromBefore = Math.min(spanFromBefore, pos2);
9724
- spanToBefore = Math.max(spanToBefore, pos2 + node.nodeSize);
9725
- }
9726
- const sharedNumId = ListHelpers.getNewListId(editor);
9727
- ListHelpers.generateNewListDefinition?.({ numId: sharedNumId, listType: TargetType, editor });
9728
- touchedLists.sort((a, b) => b.pos - a.pos);
9729
- for (const { node: oldList, pos: pos2 } of touchedLists) {
9730
- const mapped = tr.mapping.map(pos2);
9731
- const newList = rebuildListNodeWithNewNum({
9732
- oldList,
9733
- toType: TargetType,
9734
- editor,
9735
- schema: editor.schema,
9736
- fixedNumId: String(sharedNumId)
9737
- });
9738
- tr.replaceWith(mapped, mapped + oldList.nodeSize, newList);
9413
+ mode = "reuse";
9414
+ const baseNumbering = firstListNode.attrs.numberingProperties || {};
9415
+ sharedNumberingProperties = {
9416
+ ...baseNumbering,
9417
+ ilvl: baseNumbering.ilvl ?? 0
9418
+ };
9739
9419
  }
9740
- setMappedSelectionSpan(tr, spanFromBefore, spanToBefore);
9741
- if (dispatch) dispatch(tr);
9742
- return true;
9420
+ } else {
9421
+ mode = "create";
9422
+ const numId = ListHelpers.getNewListId(editor);
9423
+ ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor });
9424
+ sharedNumberingProperties = {
9425
+ numId: Number(numId),
9426
+ ilvl: 0
9427
+ };
9743
9428
  }
9744
- const { from: from2, to, empty: empty2 } = selection;
9745
- const collectParagraphs = () => {
9746
- const out = [];
9747
- doc2.nodesBetween(from2, to, (node, pos2) => {
9748
- if (node.type.name === "paragraph") {
9749
- const nodeFrom = pos2;
9750
- const nodeTo = pos2 + node.nodeSize;
9751
- if (nodeFrom < to && nodeTo > from2) out.push({ node, pos: pos2 });
9752
- return false;
9753
- }
9754
- return true;
9755
- });
9756
- return out;
9757
- };
9758
- if (!empty2 && from2 !== to) {
9759
- const paragraphs = collectParagraphs();
9760
- if (paragraphs.length >= 1) {
9761
- const first2 = paragraphs[0];
9762
- const last = paragraphs[paragraphs.length - 1];
9763
- const spanFromBefore = first2.pos;
9764
- const spanToBefore = last.pos + last.node.nodeSize;
9765
- const containers2 = buildListContainersFromParagraphs({
9766
- paragraphs,
9767
- targetKind,
9768
- editor,
9769
- schema: editor.schema
9770
- });
9771
- const replacement = paragraphs.length === 1 ? containers2[0] : Fragment.from(containers2);
9772
- tr.replaceWith(spanFromBefore, spanToBefore, replacement);
9773
- if (paragraphs.length === 1) {
9774
- setCaretInsideFirstTextblockOfNodeAt(tr, spanFromBefore);
9775
- } else {
9776
- setMappedSelectionSpan(tr, spanFromBefore, spanToBefore);
9777
- }
9778
- if (dispatch) dispatch(tr);
9779
- return true;
9429
+ for (const { node, pos } of paragraphsInSelection) {
9430
+ if (mode === "remove") {
9431
+ updateNumberingProperties(null, node, pos, editor, tr);
9432
+ continue;
9780
9433
  }
9434
+ if (mode === "reuse" && predicate(node)) {
9435
+ continue;
9436
+ }
9437
+ updateNumberingProperties(sharedNumberingProperties, node, pos, editor, tr);
9781
9438
  }
9782
- const paraAtCursor = findParentNode((n) => n.type.name === "paragraph")(selection);
9783
- if (!paraAtCursor) return false;
9784
- const { node: paragraph, pos } = paraAtCursor;
9785
- const containers = buildListContainersFromParagraphs({
9786
- paragraphs: [{ node: paragraph, pos }],
9787
- targetKind,
9788
- editor,
9789
- schema: editor.schema
9790
- });
9791
- tr.replaceWith(pos, pos + paragraph.nodeSize, containers[0]);
9792
- setCaretInsideFirstTextblockOfNodeAt(tr, pos);
9793
9439
  if (dispatch) dispatch(tr);
9794
9440
  return true;
9795
9441
  };
9796
- const LIST_NODE_NAMES = /* @__PURE__ */ new Set(["orderedList", "bulletList"]);
9797
- const parseLevel = (value) => {
9798
- if (typeof value === "number") return value;
9799
- const parsed = parseInt(value, 10);
9800
- return Number.isNaN(parsed) ? 0 : parsed;
9801
- };
9802
- const resolveParentList = ($pos) => {
9803
- if (!$pos) return null;
9804
- for (let depth = $pos.depth; depth >= 0; depth--) {
9805
- const node = $pos.node(depth);
9806
- if (node?.type && LIST_NODE_NAMES.has(node.type.name)) {
9807
- return node;
9808
- }
9442
+ const increaseListIndent = () => ({ editor, tr, dispatch }) => {
9443
+ const handled = changeListLevel(1, editor, tr);
9444
+ if (handled && dispatch) {
9445
+ dispatch(tr);
9809
9446
  }
9810
- return null;
9447
+ return handled;
9811
9448
  };
9812
- const collectTargetListItemPositions = (state, fallbackPos) => {
9813
- const doc2 = state?.doc;
9814
- const listItemType = state?.schema?.nodes?.listItem;
9815
- if (!doc2 || !listItemType) {
9816
- return typeof fallbackPos === "number" ? [fallbackPos] : [];
9817
- }
9818
- const candidates = [];
9819
- const { from: from2, to } = state.selection;
9820
- doc2.nodesBetween(from2, to, (node, pos) => {
9821
- if (node.type === listItemType) {
9822
- const size = typeof node.nodeSize === "number" ? node.nodeSize : 0;
9823
- candidates.push({ node, pos, end: pos + size });
9824
- }
9825
- });
9826
- if (!candidates.length && typeof fallbackPos === "number") {
9827
- return [fallbackPos];
9449
+ const decreaseListIndent = () => ({ editor, tr, dispatch }) => {
9450
+ const handled = changeListLevel(-1, editor, tr);
9451
+ if (handled && dispatch) {
9452
+ dispatch(tr);
9828
9453
  }
9829
- const filtered = candidates.filter(({ pos, end: end2 }) => {
9830
- return !candidates.some((other) => other.pos > pos && other.pos < end2);
9831
- });
9832
- const sorted = filtered.map(({ pos }) => pos).sort((a, b) => a - b);
9833
- return sorted.filter((pos, index2) => index2 === 0 || pos !== sorted[index2 - 1]);
9454
+ return handled;
9834
9455
  };
9835
- const decreaseListIndent = (_targetPositions) => ({ editor, tr }) => {
9836
- const { state } = editor;
9837
- const currentItem = ListHelpers.getCurrentListItem && ListHelpers.getCurrentListItem(state) || findParentNode((n) => n.type && n.type.name === "listItem")(state.selection);
9838
- const parentOrderedHelper = ListHelpers.getParentOrderedList && ListHelpers.getParentOrderedList(state);
9839
- const parentBulletHelper = ListHelpers.getParentBulletList && ListHelpers.getParentBulletList(state);
9840
- const targetPositions = _targetPositions || collectTargetListItemPositions(state, currentItem?.pos);
9841
- if (!targetPositions.length) return false;
9842
- let parentListsMap = {};
9843
- const mappedNodes = targetPositions.map((originalPos) => {
9844
- const mappedPos = tr.mapping ? tr.mapping.map(originalPos) : originalPos;
9845
- const node = tr.doc && tr.doc.nodeAt(mappedPos) || (currentItem && originalPos === currentItem.pos ? currentItem.node : null);
9846
- return { originalPos, mappedPos, node };
9847
- });
9848
- const validNodes = mappedNodes.filter(({ node }) => node && node.type.name === "listItem");
9849
- validNodes.forEach(({ mappedPos, node }) => {
9850
- const attrs = node.attrs || {};
9851
- const currLevel = parseLevel(attrs.level);
9852
- if (currLevel <= 0) {
9853
- return;
9854
- }
9855
- const newLevel = currLevel - 1;
9856
- const $pos = tr.doc ? tr.doc.resolve(mappedPos) : null;
9857
- const parentListNode = resolveParentList($pos) || parentOrderedHelper?.node || parentBulletHelper?.node || parentOrderedHelper || parentBulletHelper;
9858
- parentListsMap[mappedPos] = parentListNode;
9859
- if (!parentListNode) {
9860
- return;
9861
- }
9862
- const fallbackListId = parentListNode.attrs?.listId ?? null;
9863
- let numId = fallbackListId ?? attrs.numId ?? null;
9864
- let createdNewId = false;
9865
- if (numId == null && ListHelpers.getNewListId) {
9866
- numId = ListHelpers.getNewListId(editor);
9867
- createdNewId = numId != null;
9868
- }
9869
- if (createdNewId && numId != null && ListHelpers.generateNewListDefinition) {
9870
- ListHelpers.generateNewListDefinition({
9871
- numId,
9872
- listType: parentListNode.type,
9873
- editor
9874
- });
9456
+ const removeNumberingProperties = ({ checkType = "startParagraph" } = {}) => (props) => {
9457
+ const { tr, state, editor, dispatch } = props;
9458
+ const { node: paragraph, pos } = findParentNode(isList)(state.selection) || {};
9459
+ if (!paragraph) return false;
9460
+ if (checkType === "empty" && !isVisuallyEmptyParagraph(paragraph)) return false;
9461
+ if (checkType === "startParagraph") {
9462
+ const { $from, empty: empty2 } = state.selection;
9463
+ if ((!empty2 || $from.parentOffset !== 0) && !isVisuallyEmptyParagraph(paragraph)) return false;
9464
+ }
9465
+ const ilvl = paragraph.attrs.numberingProperties.ilvl;
9466
+ if (ilvl > 0) {
9467
+ const outdented = decreaseListIndent()(props);
9468
+ if (outdented) {
9469
+ tr.scrollIntoView();
9875
9470
  }
9876
- tr.setNodeMarkup(mappedPos, null, {
9877
- ...attrs,
9878
- level: newLevel,
9879
- numId
9880
- });
9881
- });
9882
- return Object.values(parentListsMap).length ? !Object.values(parentListsMap).every((pos) => !pos) : true;
9471
+ return outdented;
9472
+ } else {
9473
+ updateNumberingProperties(null, paragraph, pos, editor, tr);
9474
+ }
9475
+ if (dispatch) dispatch(tr);
9476
+ return true;
9883
9477
  };
9884
9478
  function isVisuallyEmptyParagraph(node) {
9885
9479
  if (!node || node.type.name !== "paragraph") return false;
@@ -9896,7 +9490,7 @@ function isVisuallyEmptyParagraph(node) {
9896
9490
  if (text.length > 0) return false;
9897
9491
  let hasInlineLeaf = false;
9898
9492
  node.descendants((n) => {
9899
- if (n.isInline && n.isLeaf && n.type?.name !== "hardBreak") {
9493
+ if (n.isInline && n.isLeaf && n.type?.name !== "hardBreak" && n.type?.name !== "run") {
9900
9494
  hasInlineLeaf = true;
9901
9495
  return false;
9902
9496
  }
@@ -9905,468 +9499,6 @@ function isVisuallyEmptyParagraph(node) {
9905
9499
  if (hasInlineLeaf) return false;
9906
9500
  return true;
9907
9501
  }
9908
- function tryOutdentOneLevel(props) {
9909
- return decreaseListIndent()(props);
9910
- }
9911
- const splitListItem = () => (props) => {
9912
- const { tr, state, dispatch } = props;
9913
- const type = getNodeType("listItem", state.schema);
9914
- const { $from, $to, empty: empty2 } = state.selection;
9915
- tr.setMeta("updateListSync", true);
9916
- const listItemPM = findParentNode((n) => n.type === type)(state.selection);
9917
- if (!listItemPM) return false;
9918
- const { node: listItemNode } = listItemPM;
9919
- if (state.selection.node && state.selection.node.isBlock || $from.depth < 2 || !$from.sameParent($to)) {
9920
- return false;
9921
- }
9922
- const paraPM = findParentNode((n) => n.type.name === "paragraph")(state.selection);
9923
- if (!paraPM) return false;
9924
- const originalParagraphNode = paraPM.node;
9925
- const paraStart = paraPM.pos + 1;
9926
- const listPM = findParentNode((n) => ["orderedList", "bulletList"].includes(n.type.name))(state.selection);
9927
- if (!listPM) return false;
9928
- const { node: parentListNode, pos: listStart } = listPM;
9929
- const listEnd = listStart + parentListNode.nodeSize;
9930
- let offsetInParagraph;
9931
- if (empty2) {
9932
- offsetInParagraph = state.selection.from - paraStart;
9933
- } else {
9934
- offsetInParagraph = $from.pos - paraStart;
9935
- }
9936
- const parentPara = $from.parent;
9937
- const isEmptyPara = isVisuallyEmptyParagraph(parentPara);
9938
- const atEndOfListItem = $from.node(-1).childCount === $from.indexAfter(-1);
9939
- if (isEmptyPara && atEndOfListItem) {
9940
- const currentLevel = typeof listItemNode?.attrs?.level === "number" ? listItemNode.attrs.level : 0;
9941
- if (currentLevel > 0) {
9942
- const outdented = tryOutdentOneLevel(props);
9943
- if (outdented) {
9944
- tr.scrollIntoView();
9945
- if (dispatch) dispatch(tr);
9946
- return true;
9947
- }
9948
- }
9949
- return handleSplitInEmptyBlock(props, listItemPM);
9950
- }
9951
- if (isVisuallyEmptyParagraph(originalParagraphNode)) {
9952
- const currentLevel = typeof listItemNode?.attrs?.level === "number" ? listItemNode.attrs.level : 0;
9953
- if (currentLevel > 0) {
9954
- const outdented = tryOutdentOneLevel(props);
9955
- if (outdented) {
9956
- tr.scrollIntoView();
9957
- if (dispatch) dispatch(tr);
9958
- return true;
9959
- }
9960
- }
9961
- return handleSplitInEmptyBlock(props, listItemPM);
9962
- }
9963
- let paragraphContentToSplit = originalParagraphNode.content;
9964
- if (!empty2) {
9965
- const selectionStart = $from.pos - paraStart;
9966
- const selectionEnd = $to.pos - paraStart;
9967
- paragraphContentToSplit = originalParagraphNode.content.cut(0, selectionStart).append(originalParagraphNode.content.cut(selectionEnd));
9968
- offsetInParagraph = selectionStart;
9969
- }
9970
- const beforeCursor = paragraphContentToSplit.cut(0, Math.max(0, offsetInParagraph));
9971
- const afterCursor = paragraphContentToSplit.cut(Math.max(0, offsetInParagraph));
9972
- const paragraphIndex = $from.index(-1);
9973
- const listItemHasMultipleParagraphs = listItemNode.childCount > 1;
9974
- let firstLI, secondLI;
9975
- if (listItemHasMultipleParagraphs) {
9976
- const contentBefore = [];
9977
- for (let i = 0; i < paragraphIndex; i++) contentBefore.push(listItemNode.child(i));
9978
- const contentAfter = [];
9979
- for (let i = paragraphIndex + 1; i < listItemNode.childCount; i++) contentAfter.push(listItemNode.child(i));
9980
- const firstParas = [
9981
- ...contentBefore,
9982
- originalParagraphNode.type.create(originalParagraphNode.attrs, beforeCursor.size ? beforeCursor : null)
9983
- ].filter(Boolean);
9984
- if (firstParas.length === 0) {
9985
- firstParas.push(state.schema.nodes.paragraph.create(originalParagraphNode.attrs));
9986
- }
9987
- const secondParas = [
9988
- originalParagraphNode.type.create(originalParagraphNode.attrs, afterCursor.size ? afterCursor : null),
9989
- ...contentAfter
9990
- ].filter(Boolean);
9991
- if (secondParas.length === 0) {
9992
- secondParas.push(state.schema.nodes.paragraph.create(originalParagraphNode.attrs));
9993
- }
9994
- firstLI = state.schema.nodes.listItem.create({ ...listItemNode.attrs }, Fragment.from(firstParas));
9995
- secondLI = state.schema.nodes.listItem.create({ ...listItemNode.attrs }, Fragment.from(secondParas));
9996
- } else {
9997
- const firstParagraph = originalParagraphNode.type.create(
9998
- originalParagraphNode.attrs,
9999
- beforeCursor.size ? beforeCursor : null
10000
- );
10001
- const secondParagraph = originalParagraphNode.type.create(
10002
- originalParagraphNode.attrs,
10003
- afterCursor.size ? afterCursor : null
10004
- );
10005
- firstLI = state.schema.nodes.listItem.create({ ...listItemNode.attrs }, firstParagraph);
10006
- secondLI = state.schema.nodes.listItem.create({ ...listItemNode.attrs }, secondParagraph);
10007
- }
10008
- if (!firstLI || !secondLI) return false;
10009
- const ListType = parentListNode.type;
10010
- const firstList = ListType.createAndFill(parentListNode.attrs, Fragment.from(firstLI));
10011
- const secondList = ListType.createAndFill(parentListNode.attrs, Fragment.from(secondLI));
10012
- if (!firstList || !secondList) return false;
10013
- tr.replaceWith(listStart, listEnd, firstList);
10014
- const insertAfterFirst = listStart + firstList.nodeSize;
10015
- tr.insert(insertAfterFirst, secondList);
10016
- const cursorPos = insertAfterFirst + 3;
10017
- tr.setSelection(TextSelection.near(tr.doc.resolve(cursorPos), 1)).scrollIntoView();
10018
- tr.setMeta("splitListItem", true);
10019
- if (dispatch) dispatch(tr);
10020
- return true;
10021
- };
10022
- const handleSplitInEmptyBlock = (props, currentListItem) => {
10023
- const { state, editor, tr } = props;
10024
- const { schema } = state;
10025
- const { $from } = state.selection;
10026
- const extensionAttrs = editor.extensionService.attributes;
10027
- const listItemNode = currentListItem.node;
10028
- const isEmptyParagraph = isVisuallyEmptyParagraph($from.parent);
10029
- const listItemHasOtherContent = listItemNode.content.size > $from.parent.nodeSize;
10030
- const isAtEndOfListItem = $from.indexAfter(-1) === $from.node(-1).childCount;
10031
- if (isEmptyParagraph && listItemHasOtherContent && isAtEndOfListItem) {
10032
- try {
10033
- const listTypes2 = ["orderedList", "bulletList"];
10034
- const parentList2 = findParentNode((n) => listTypes2.includes(n.type.name))(state.selection);
10035
- if (!parentList2) return false;
10036
- const newParagraphAttrs2 = Attribute.getSplittedAttributes(extensionAttrs, "paragraph", {});
10037
- const newParagraph2 = schema.nodes.paragraph.create(newParagraphAttrs2);
10038
- const newListItem = schema.nodes.listItem.create({ ...listItemNode.attrs }, newParagraph2);
10039
- const ListType = parentList2.node.type;
10040
- const newList = ListType.createAndFill(parentList2.node.attrs, Fragment.from(newListItem));
10041
- if (!newList) return false;
10042
- const insertPos = parentList2.pos + parentList2.node.nodeSize;
10043
- tr.insert(insertPos, newList);
10044
- const newPos2 = insertPos + 3;
10045
- tr.setSelection(TextSelection.near(tr.doc.resolve(newPos2)));
10046
- tr.scrollIntoView();
10047
- return true;
10048
- } catch (e) {
10049
- console.error("Error creating new list item:", e);
10050
- return false;
10051
- }
10052
- }
10053
- if (isEmptyParagraph && listItemHasOtherContent && !isAtEndOfListItem) return false;
10054
- const listTypes = ["orderedList", "bulletList"];
10055
- const parentList = findParentNode((n) => listTypes.includes(n.type.name))(state.selection);
10056
- if (!parentList) return false;
10057
- const newParagraphAttrs = Attribute.getSplittedAttributes(extensionAttrs, "paragraph", {});
10058
- let newParagraph = schema.nodes.paragraph.createAndFill(newParagraphAttrs);
10059
- if (!newParagraph) newParagraph = schema.nodes.paragraph.create();
10060
- const listStart = parentList.pos;
10061
- const listEnd = parentList.pos + parentList.node.nodeSize;
10062
- tr.replaceWith(listStart, listEnd, newParagraph);
10063
- const newPos = listStart + 1;
10064
- tr.setSelection(TextSelection.near(tr.doc.resolve(newPos)));
10065
- tr.scrollIntoView();
10066
- return true;
10067
- };
10068
- const sinkListItem = (typeOrName) => ({ state, dispatch }) => {
10069
- const type = getNodeType(typeOrName, state.schema);
10070
- return sinkListItem$1(type)(state, dispatch);
10071
- };
10072
- const liftListItem = (typeOrName) => ({ state, dispatch }) => {
10073
- const type = getNodeType(typeOrName, state.schema);
10074
- return liftListItem$1(type)(state, dispatch);
10075
- };
10076
- const deleteListItem = () => (props) => {
10077
- const { tr, state } = props;
10078
- const { selection } = state;
10079
- tr.setMeta("updateListSync", true);
10080
- if (!selection.empty) {
10081
- const { from: from2, to } = selection;
10082
- const fullySelectedBlocks = [];
10083
- state.doc.nodesBetween(from2, to, (node, pos) => {
10084
- if (node.isBlock && pos >= from2 && pos + node.nodeSize <= to) {
10085
- fullySelectedBlocks.push({ pos, size: node.nodeSize });
10086
- }
10087
- });
10088
- if (fullySelectedBlocks.length) {
10089
- fullySelectedBlocks.sort((a, b) => b.pos - a.pos).forEach(({ pos, size }) => {
10090
- tr.delete(pos, pos + size);
10091
- });
10092
- const $new = tr.doc.resolve(from2);
10093
- tr.setSelection(TextSelection.near($new));
10094
- return true;
10095
- }
10096
- return false;
10097
- }
10098
- const { $from } = state.selection;
10099
- if ($from.parentOffset !== 0) return false;
10100
- const currentListItem = findParentNode((n) => n.type.name === "listItem")(state.selection);
10101
- if (!currentListItem) return false;
10102
- const listTypes = ["orderedList", "bulletList"];
10103
- const parentList = findParentNode((n) => listTypes.includes(n.type.name))(state.selection);
10104
- if (!parentList) return false;
10105
- const currentParagraphNode = findParentNode((n) => n.type.name === "paragraph")(state.selection);
10106
- const paragraphNode = currentListItem.node.content.firstChild;
10107
- if (paragraphNode !== currentParagraphNode.node) return false;
10108
- const listFrom = parentList.pos;
10109
- const listTo = listFrom + parentList.node.nodeSize;
10110
- if (currentListItem.node.content.size === 0) {
10111
- tr.delete(listFrom, listTo);
10112
- return true;
10113
- }
10114
- const listItemContent = currentListItem.node.content;
10115
- const nodes = [];
10116
- listItemContent.forEach((child) => {
10117
- nodes.push(child);
10118
- });
10119
- tr.replaceWith(listFrom, listTo, nodes);
10120
- const $pos = tr.doc.resolve(listFrom + 1);
10121
- tr.setSelection(TextSelection.near($pos));
10122
- return true;
10123
- };
10124
- const increaseListIndent = (_targetPositions) => ({ editor, tr }) => {
10125
- const { state } = editor;
10126
- const currentItem = ListHelpers.getCurrentListItem && ListHelpers.getCurrentListItem(state) || findParentNode((n) => n.type && n.type.name === "listItem")(state.selection);
10127
- const parentOrderedHelper = ListHelpers.getParentOrderedList && ListHelpers.getParentOrderedList(state);
10128
- const parentBulletHelper = ListHelpers.getParentBulletList && ListHelpers.getParentBulletList(state);
10129
- const targetPositions = _targetPositions || collectTargetListItemPositions(state, currentItem?.pos);
10130
- if (!targetPositions.length) return false;
10131
- let parentListsMap = {};
10132
- const mappedNodes = targetPositions.map((originalPos) => {
10133
- const mappedPos = tr.mapping ? tr.mapping.map(originalPos) : originalPos;
10134
- const node = tr.doc && tr.doc.nodeAt(mappedPos) || (currentItem && originalPos === currentItem.pos ? currentItem.node : null);
10135
- return { originalPos, mappedPos, node };
10136
- });
10137
- const validNodes = mappedNodes.filter(({ node }) => node && node.type.name === "listItem");
10138
- validNodes.forEach(({ mappedPos, node }) => {
10139
- const attrs = node.attrs || {};
10140
- const currentLevel = parseLevel(attrs.level);
10141
- const newLevel = currentLevel + 1;
10142
- const $pos = tr.doc ? tr.doc.resolve(mappedPos) : null;
10143
- const parentListNode = resolveParentList($pos) || parentOrderedHelper?.node || parentBulletHelper?.node || parentOrderedHelper || parentBulletHelper;
10144
- parentListsMap[mappedPos] = parentListNode;
10145
- if (!parentListNode) {
10146
- return;
10147
- }
10148
- let numId = attrs.numId;
10149
- if (numId == null) {
10150
- const fallbackListId = parentListNode.attrs?.listId ?? null;
10151
- numId = fallbackListId ?? (ListHelpers.getNewListId ? ListHelpers.getNewListId(editor) : null);
10152
- if (numId != null && ListHelpers.generateNewListDefinition) {
10153
- ListHelpers.generateNewListDefinition({
10154
- numId,
10155
- listType: parentListNode.type,
10156
- editor
10157
- });
10158
- }
10159
- }
10160
- tr.setNodeMarkup(mappedPos, null, {
10161
- ...attrs,
10162
- level: newLevel,
10163
- numId
10164
- });
10165
- });
10166
- return Object.values(parentListsMap).length ? !Object.values(parentListsMap).every((pos) => !pos) : true;
10167
- };
10168
- const isList = (n) => !!n && (n.type?.name === "orderedList" || n.type?.name === "bulletList");
10169
- const findNodePosition = (doc2, targetNode) => {
10170
- let nodePos = null;
10171
- doc2.descendants((node, pos) => {
10172
- if (node === targetNode) {
10173
- nodePos = pos;
10174
- return false;
10175
- }
10176
- return true;
10177
- });
10178
- return nodePos;
10179
- };
10180
- function getListContext(state) {
10181
- const { $from } = state.selection;
10182
- for (let d2 = $from.depth; d2 > 0; d2--) {
10183
- const node = $from.node(d2 - 1);
10184
- if (isList(node)) {
10185
- const listDepth = d2 - 1;
10186
- const listPos = $from.before(listDepth);
10187
- const listNode = node;
10188
- const liNode = listNode.firstChild || null;
10189
- if (!liNode || liNode.type.name !== "listItem") return null;
10190
- return { listDepth, listPos, listNode, liNode };
10191
- }
10192
- }
10193
- return null;
10194
- }
10195
- const handleBackspaceNextToList = () => ({ state, dispatch, editor }) => {
10196
- const { selection, doc: doc2, schema } = state;
10197
- const { $from } = selection;
10198
- if (!selection.empty) return false;
10199
- if ($from.parent.type.name !== "paragraph") return false;
10200
- const ctx = getListContext(state);
10201
- if (ctx) {
10202
- const { listPos, listNode, liNode } = ctx;
10203
- const atStartOfParagraph = $from.parentOffset === 0;
10204
- const itemIsEmpty = liNode.childCount > 0 ? liNode.firstChild?.content.size === 0 : true;
10205
- if (!atStartOfParagraph && !itemIsEmpty) return false;
10206
- const level = Number(liNode.attrs?.level ?? 0);
10207
- if (level > 0) {
10208
- const tr1 = state.tr.setMeta("updateListSync", true);
10209
- const didOutdent = typeof decreaseListIndent === "function" && decreaseListIndent()({
10210
- editor,
10211
- state,
10212
- tr: tr1,
10213
- dispatch: (t) => dispatch && t && dispatch(t)
10214
- });
10215
- if (didOutdent) return true;
10216
- const liPos = listPos + 1;
10217
- const newLevel = Math.max(0, level - 1);
10218
- const trFallback = state.tr.setMeta("updateListSync", true);
10219
- trFallback.setNodeMarkup(liPos, null, { ...liNode.attrs, level: newLevel });
10220
- dispatch(trFallback);
10221
- return true;
10222
- }
10223
- const replacement = liNode && liNode.content && liNode.content.size > 0 ? liNode.content : Fragment.from(schema.nodes.paragraph.create());
10224
- const from2 = listPos;
10225
- const to = listPos + listNode.nodeSize;
10226
- const tr2 = state.tr.setMeta("updateListSync", true);
10227
- tr2.replaceWith(from2, to, replacement);
10228
- const newPos = from2 + 1;
10229
- tr2.setSelection(TextSelection.near(tr2.doc.resolve(newPos), 1)).scrollIntoView();
10230
- dispatch(tr2);
10231
- return true;
10232
- }
10233
- if ($from.parentOffset !== 0) return false;
10234
- const parentDepth = $from.depth - 1;
10235
- if (parentDepth < 0) return false;
10236
- const container = $from.node(parentDepth);
10237
- const idx = $from.index(parentDepth);
10238
- if (idx === 0) return false;
10239
- const beforeNode = container.child(idx - 1);
10240
- if (!beforeNode || !isList(beforeNode)) return false;
10241
- const listItem = beforeNode.lastChild;
10242
- if (!listItem || listItem.type.name !== "listItem") return false;
10243
- const targetPara = listItem.lastChild;
10244
- if (!targetPara || targetPara.type.name !== "paragraph") return false;
10245
- const paraStartPos = findNodePosition(doc2, targetPara);
10246
- if (paraStartPos == null) return false;
10247
- const inlineContent = Fragment.from($from.parent.content);
10248
- const tr = state.tr.setMeta("updateListSync", true);
10249
- const thisParaStart = $from.before();
10250
- tr.delete(thisParaStart, thisParaStart + $from.parent.nodeSize);
10251
- const insertPos = paraStartPos + 1 + targetPara.content.size;
10252
- tr.insert(insertPos, inlineContent);
10253
- tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos), 1));
10254
- dispatch(tr);
10255
- return true;
10256
- };
10257
- function getParaCtx(state) {
10258
- const { $from } = state.selection;
10259
- for (let d2 = $from.depth; d2 >= 0; d2--) {
10260
- const n = $from.node(d2);
10261
- if (n.type.name === "paragraph") {
10262
- const before = $from.before(d2);
10263
- const endInside = before + 1 + n.content.size;
10264
- return { para: n, paraDepth: d2, before, endInside };
10265
- }
10266
- }
10267
- return null;
10268
- }
10269
- function atVisualParaEnd(state, ctx) {
10270
- const { $from } = state.selection;
10271
- const { para, paraDepth, endInside } = ctx;
10272
- if ($from.parent.type.name === "paragraph" && $from.parentOffset === $from.parent.content.size) return true;
10273
- if ($from.parent.type.name === "run" && $from.parentOffset === $from.parent.content.size) {
10274
- const idxInPara = $from.index(paraDepth);
10275
- return idxInPara === para.childCount - 1;
10276
- }
10277
- return $from.pos === endInside;
10278
- }
10279
- function getNextSiblingAtDepth(state, depth) {
10280
- const pos = state.selection.$from.after(depth);
10281
- if (pos == null) return { pos: null, next: null };
10282
- const $pos = state.doc.resolve(pos);
10283
- return { pos, next: $pos.nodeAfter || null };
10284
- }
10285
- const handleDeleteNextToList = () => ({ state, dispatch }) => {
10286
- const { selection } = state;
10287
- const { $from } = selection;
10288
- if (!selection.empty) return false;
10289
- const ctx = getParaCtx(state);
10290
- if (!ctx) return false;
10291
- const { paraDepth, endInside: paraEnd } = ctx;
10292
- if (!atVisualParaEnd(state, ctx)) return false;
10293
- const tr = state.tr;
10294
- tr.setMeta("suppressAutoList", true);
10295
- const insertAtParaEnd = (frag) => {
10296
- const mapped = tr.mapping.map(paraEnd, 1);
10297
- tr.insert(mapped, frag);
10298
- return mapped;
10299
- };
10300
- let listItemDepth = -1;
10301
- let listDepth = -1;
10302
- for (let d2 = $from.depth; d2 > 0; d2--) {
10303
- const maybeLI = $from.node(d2 - 1);
10304
- if (maybeLI.type.name === "listItem") {
10305
- listItemDepth = d2 - 1;
10306
- if (d2 - 2 >= 0 && isList($from.node(d2 - 2))) listDepth = d2 - 2;
10307
- break;
10308
- }
10309
- }
10310
- if (listItemDepth !== -1 && listDepth !== -1) {
10311
- const li = $from.node(listItemDepth);
10312
- const paraIdxInLI = $from.index(listItemDepth + 1);
10313
- if (paraIdxInLI < li.childCount - 1) return false;
10314
- }
10315
- const currentBlockDepth = listItemDepth !== -1 && listDepth !== -1 ? listDepth : paraDepth;
10316
- const { pos: nextBeforePos, next: nextNode } = getNextSiblingAtDepth(state, currentBlockDepth);
10317
- if (nextBeforePos == null || !nextNode) return false;
10318
- const mergeParagraphAt = (beforePos) => {
10319
- const livePara = tr.doc.resolve(beforePos).nodeAfter;
10320
- if (!livePara || livePara.type.name !== "paragraph") return false;
10321
- if (livePara.content.size === 0) {
10322
- tr.delete(beforePos, beforePos + livePara.nodeSize);
10323
- dispatch?.(tr);
10324
- return true;
10325
- }
10326
- const ins = insertAtParaEnd(Fragment.from(livePara.content));
10327
- const delFrom = tr.mapping.map(beforePos, 1);
10328
- const delTo = tr.mapping.map(beforePos + livePara.nodeSize, 1);
10329
- tr.delete(delFrom, delTo);
10330
- const selPos = tr.mapping.map(ins + livePara.content.size, -1);
10331
- tr.setSelection(TextSelection.near(tr.doc.resolve(selPos), -1)).scrollIntoView();
10332
- dispatch?.(tr);
10333
- return true;
10334
- };
10335
- const mergeListAt = (beforePos) => {
10336
- const liveList = tr.doc.resolve(beforePos).nodeAfter;
10337
- if (!liveList || !isList(liveList)) return true;
10338
- const li = liveList.firstChild;
10339
- if (!li || li.type.name !== "listItem" || li.childCount === 0) {
10340
- tr.delete(beforePos, beforePos + liveList.nodeSize);
10341
- dispatch?.(tr);
10342
- return true;
10343
- }
10344
- let content = null;
10345
- for (let i = 0; i < li.childCount; i++) {
10346
- const ch = li.child(i);
10347
- if (ch.type.name === "paragraph" && ch.content.size > 0) {
10348
- content = ch.content;
10349
- break;
10350
- }
10351
- }
10352
- if (content) insertAtParaEnd(Fragment.from(content));
10353
- const delFrom = tr.mapping.map(beforePos, 1);
10354
- const delTo = tr.mapping.map(beforePos + liveList.nodeSize, 1);
10355
- tr.delete(delFrom, delTo);
10356
- const endPos = tr.mapping.map(paraEnd + (content ? content.size : 0), -1);
10357
- tr.setSelection(TextSelection.near(tr.doc.resolve(endPos), -1)).scrollIntoView();
10358
- dispatch?.(tr);
10359
- return true;
10360
- };
10361
- if (nextNode.isTextblock) {
10362
- const changed = mergeParagraphAt(nextBeforePos);
10363
- return changed ? true : false;
10364
- }
10365
- if (isList(nextNode)) {
10366
- return mergeListAt(nextBeforePos);
10367
- }
10368
- return false;
10369
- };
10370
9502
  const restoreSelection = () => ({ editor, state, tr }) => {
10371
9503
  if (editor.options.lastSelection) {
10372
9504
  const selectionTr = tr.setSelection(
@@ -10420,23 +9552,18 @@ const getSelectionMarks = () => ({ state, tr }) => {
10420
9552
  };
10421
9553
  const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
10422
9554
  __proto__: null,
10423
- atVisualParaEnd,
9555
+ changeListLevel,
10424
9556
  clearNodes,
10425
- collectIntersectingTopLists,
10426
9557
  command,
10427
9558
  createParagraphNear,
10428
9559
  decreaseListIndent,
10429
9560
  defaultStyleDetector,
10430
- deleteListItem,
10431
9561
  deleteSelection,
10432
9562
  exitCode,
10433
9563
  first,
10434
9564
  getEffectiveStyleId,
10435
- getParaCtx,
10436
9565
  getSelectionMarks,
10437
9566
  getStyleIdFromMarks,
10438
- handleBackspaceNextToList,
10439
- handleDeleteNextToList,
10440
9567
  increaseListIndent,
10441
9568
  insertContent,
10442
9569
  insertContentAt,
@@ -10449,11 +9576,9 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10449
9576
  joinForward,
10450
9577
  joinUp,
10451
9578
  liftEmptyBlock,
10452
- liftListItem,
10453
9579
  mapMarkToStyleKey,
10454
- nearestListAt,
10455
9580
  newlineInCode,
10456
- rebuildListNodeWithNewNum,
9581
+ removeNumberingProperties,
10457
9582
  resetAttributes,
10458
9583
  restoreSelection,
10459
9584
  selectAll,
@@ -10461,14 +9586,11 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10461
9586
  selectNodeForward,
10462
9587
  selectTextblockEnd,
10463
9588
  selectTextblockStart,
10464
- setMappedSelectionSpan,
10465
9589
  setMark,
10466
9590
  setMeta,
10467
9591
  setNode,
10468
9592
  setTextSelection,
10469
- sinkListItem,
10470
9593
  splitBlock: splitBlock$1,
10471
- splitListItem,
10472
9594
  toggleList,
10473
9595
  toggleMark,
10474
9596
  toggleMarkCascade,
@@ -10477,7 +9599,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
10477
9599
  unsetAllMarks,
10478
9600
  unsetMark,
10479
9601
  updateAttributes,
10480
- wrapInList
9602
+ updateNumberingProperties
10481
9603
  }, Symbol.toStringTag, { value: "Module" }));
10482
9604
  const Commands = Extension.create({
10483
9605
  name: "commands",
@@ -10502,8 +9624,7 @@ const handleBackspace = (editor) => {
10502
9624
  return false;
10503
9625
  },
10504
9626
  () => commands2.deleteSelection(),
10505
- () => commands2.handleBackspaceNextToList(),
10506
- () => commands2.deleteListItem(),
9627
+ () => commands2.removeNumberingProperties(),
10507
9628
  () => commands2.joinBackward(),
10508
9629
  () => commands2.selectNodeBackward()
10509
9630
  ]);
@@ -10511,7 +9632,6 @@ const handleBackspace = (editor) => {
10511
9632
  const handleDelete = (editor) => {
10512
9633
  return editor.commands.first(({ commands: commands2 }) => [
10513
9634
  () => commands2.deleteSelection(),
10514
- () => commands2.handleDeleteNextToList(),
10515
9635
  () => commands2.joinForward(),
10516
9636
  () => commands2.selectNodeForward()
10517
9637
  ]);
@@ -11028,7 +10148,8 @@ const _ExtensionService = class _ExtensionService {
11028
10148
  getPos,
11029
10149
  decorations,
11030
10150
  htmlAttributes,
11031
- extension
10151
+ extension,
10152
+ extensionAttrs
11032
10153
  });
11033
10154
  };
11034
10155
  return [extension.name, nodeview];
@@ -15081,7 +14202,7 @@ const _Editor = class _Editor extends EventEmitter {
15081
14202
  { default: remarkStringify },
15082
14203
  { default: remarkGfm }
15083
14204
  ] = await Promise.all([
15084
- import("./index-BJia6SL_.js"),
14205
+ import("./index-D6-7DIFN.js"),
15085
14206
  import("./index-DRCvimau.js"),
15086
14207
  import("./index-C_x_N6Uh.js"),
15087
14208
  import("./index-D_sWOSiG.js"),
@@ -15299,7 +14420,7 @@ const _Editor = class _Editor extends EventEmitter {
15299
14420
  * @returns {Object | void} Migration results
15300
14421
  */
15301
14422
  processCollaborationMigrations() {
15302
- console.debug("[checkVersionMigrations] Current editor version", "0.30.0-next.2");
14423
+ console.debug("[checkVersionMigrations] Current editor version", "0.30.0-next.4");
15303
14424
  if (!this.options.ydoc) return;
15304
14425
  const metaMap = this.options.ydoc.getMap("meta");
15305
14426
  let docVersion = metaMap.get("version");
@@ -15404,7 +14525,7 @@ const _Editor = class _Editor extends EventEmitter {
15404
14525
  if (!targetNode || !html) return;
15405
14526
  const start2 = targetNode.pos;
15406
14527
  const end2 = start2 + targetNode.node.nodeSize;
15407
- const htmlNode = createDocFromHTML(html, this.schema);
14528
+ const htmlNode = createDocFromHTML(html, this);
15408
14529
  tr.replaceWith(start2, end2, htmlNode);
15409
14530
  dispatch(tr);
15410
14531
  }
@@ -15779,14 +14900,14 @@ generatePmData_fn = function() {
15779
14900
  doc2 = createDocument(this.converter, this.schema, this);
15780
14901
  doc2 = __privateMethod(this, _Editor_instances, prepareDocumentForImport_fn).call(this, doc2);
15781
14902
  if (this.options.markdown) {
15782
- doc2 = createDocFromMarkdown(this.options.markdown, this.schema, { isImport: true });
15783
- } else if (this.options.html) doc2 = createDocFromHTML(this.options.html, this.schema, { isImport: true });
14903
+ doc2 = createDocFromMarkdown(this.options.markdown, this, { isImport: true });
14904
+ } else if (this.options.html) doc2 = createDocFromHTML(this.options.html, this, { isImport: true });
15784
14905
  else if (this.options.jsonOverride) doc2 = this.schema.nodeFromJSON(this.options.jsonOverride);
15785
14906
  if (fragment) doc2 = yXmlFragmentToProseMirrorRootNode(fragment, this.schema);
15786
14907
  }
15787
14908
  } else if (mode === "text" || mode === "html") {
15788
14909
  if (loadFromSchema) doc2 = this.schema.nodeFromJSON(content);
15789
- else if (content) doc2 = createDocFromHTML(content, this.schema);
14910
+ else if (content) doc2 = createDocFromHTML(content, this);
15790
14911
  else doc2 = this.schema.topNodeType.createAndFill();
15791
14912
  }
15792
14913
  } catch (err) {
@@ -18634,7 +17755,7 @@ const splitRun = () => (props) => {
18634
17755
  const { $from, empty: empty2 } = state.selection;
18635
17756
  if (!empty2) return false;
18636
17757
  if ($from.parent.type.name !== "run") return false;
18637
- const handled = splitBlock(state, (transaction) => {
17758
+ const handled = splitBlockPatch(state, (transaction) => {
18638
17759
  view.dispatch(transaction);
18639
17760
  });
18640
17761
  if (handled) {
@@ -18642,6 +17763,48 @@ const splitRun = () => (props) => {
18642
17763
  }
18643
17764
  return handled;
18644
17765
  };
17766
+ function splitBlockPatch(state, dispatch) {
17767
+ let { $from } = state.selection;
17768
+ if (state.selection instanceof NodeSelection && state.selection.node.isBlock) {
17769
+ if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) return false;
17770
+ if (dispatch) dispatch(state.tr.split($from.pos).scrollIntoView());
17771
+ return true;
17772
+ }
17773
+ if (!$from.depth) return false;
17774
+ let types = [];
17775
+ let splitDepth, deflt, atEnd = false, atStart = false;
17776
+ for (let d2 = $from.depth; ; d2--) {
17777
+ let node = $from.node(d2);
17778
+ if (node.isBlock) {
17779
+ atEnd = $from.end(d2) == $from.pos + ($from.depth - d2);
17780
+ atStart = $from.start(d2) == $from.pos - ($from.depth - d2);
17781
+ deflt = defaultBlockAt$1($from.node(d2 - 1).contentMatchAt($from.indexAfter(d2 - 1)));
17782
+ types.unshift(null);
17783
+ splitDepth = d2;
17784
+ break;
17785
+ } else {
17786
+ if (d2 == 1) return false;
17787
+ types.unshift(null);
17788
+ }
17789
+ }
17790
+ let tr = state.tr;
17791
+ if (state.selection instanceof TextSelection || state.selection instanceof AllSelection) tr.deleteSelection();
17792
+ let splitPos = tr.mapping.map($from.pos);
17793
+ let can = canSplit(tr.doc, splitPos, types.length, types);
17794
+ if (!can) {
17795
+ types[0] = deflt ? { type: deflt } : null;
17796
+ can = canSplit(tr.doc, splitPos, types.length, types);
17797
+ }
17798
+ if (!can) return false;
17799
+ tr.split(splitPos, types.length, types);
17800
+ if (!atEnd && atStart && $from.node(splitDepth).type != deflt) {
17801
+ let first2 = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first2);
17802
+ if (deflt && $from.node(splitDepth - 1).canReplaceWith($first.index(), $first.index() + 1, deflt))
17803
+ tr.setNodeMarkup(tr.mapping.map($from.before(splitDepth)), deflt);
17804
+ }
17805
+ if (dispatch) dispatch(tr.scrollIntoView());
17806
+ return true;
17807
+ }
18645
17808
  const Run = OxmlNode.create({
18646
17809
  name: "run",
18647
17810
  oXmlName: "w:r",
@@ -18694,387 +17857,6 @@ const Run = OxmlNode.create({
18694
17857
  return ["span", base2, 0];
18695
17858
  }
18696
17859
  });
18697
- const inputRegex$1 = /^\s*([-+*])\s$/;
18698
- const BulletList = Node$1.create({
18699
- name: "bulletList",
18700
- group: "block list",
18701
- selectable: false,
18702
- content() {
18703
- return `${this.options.itemTypeName}+`;
18704
- },
18705
- addOptions() {
18706
- return {
18707
- itemTypeName: "listItem",
18708
- htmlAttributes: {
18709
- "aria-label": "Bullet list node"
18710
- },
18711
- keepMarks: true,
18712
- keepAttributes: false
18713
- };
18714
- },
18715
- parseDOM() {
18716
- return [{ tag: "ul" }];
18717
- },
18718
- renderDOM({ htmlAttributes }) {
18719
- const attributes = Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes);
18720
- return ["ul", attributes, 0];
18721
- },
18722
- addAttributes() {
18723
- return {
18724
- "list-style-type": {
18725
- default: "bullet",
18726
- rendered: false
18727
- },
18728
- listId: {
18729
- rendered: false
18730
- },
18731
- sdBlockId: {
18732
- default: null,
18733
- keepOnSplit: false,
18734
- parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
18735
- renderDOM: (attrs) => {
18736
- return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
18737
- }
18738
- },
18739
- attributes: {
18740
- rendered: false,
18741
- keepOnSplit: true
18742
- }
18743
- };
18744
- },
18745
- addCommands() {
18746
- return {
18747
- /**
18748
- * Toggle a bullet list at the current selection
18749
- * @category Command
18750
- * @example
18751
- * // Toggle bullet list on selected text
18752
- * editor.commands.toggleBulletList()
18753
- * @note Converts selected paragraphs to list items or removes list formatting
18754
- */
18755
- toggleBulletList: () => (params2) => {
18756
- return toggleList(this.type)(params2);
18757
- }
18758
- };
18759
- },
18760
- addShortcuts() {
18761
- return {
18762
- "Mod-Shift-8": () => {
18763
- return this.editor.commands.toggleBulletList();
18764
- }
18765
- };
18766
- },
18767
- addInputRules() {
18768
- return [
18769
- new InputRule({
18770
- match: inputRegex$1,
18771
- handler: ({ state, range }) => {
18772
- const $pos = state.selection.$from;
18773
- const listItemType = state.schema.nodes.listItem;
18774
- for (let depth = $pos.depth; depth >= 0; depth--) {
18775
- if ($pos.node(depth).type === listItemType) {
18776
- return null;
18777
- }
18778
- }
18779
- const { tr } = state;
18780
- tr.delete(range.from, range.to);
18781
- ListHelpers.createNewList({
18782
- listType: this.type,
18783
- tr,
18784
- editor: this.editor
18785
- });
18786
- }
18787
- })
18788
- ];
18789
- }
18790
- });
18791
- const inputRegex = /^(\d+)\.\s$/;
18792
- const OrderedList = Node$1.create({
18793
- name: "orderedList",
18794
- group: "block list",
18795
- selectable: false,
18796
- content() {
18797
- return `${this.options.itemTypeName}+`;
18798
- },
18799
- addOptions() {
18800
- return {
18801
- itemTypeName: "listItem",
18802
- htmlAttributes: {
18803
- "aria-label": "Ordered list node"
18804
- },
18805
- keepMarks: true,
18806
- keepAttributes: false,
18807
- listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
18808
- };
18809
- },
18810
- addAttributes() {
18811
- return {
18812
- order: {
18813
- default: 1,
18814
- parseDOM: (element) => {
18815
- return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
18816
- },
18817
- renderDOM: (attrs) => {
18818
- return {
18819
- start: attrs.order
18820
- };
18821
- }
18822
- },
18823
- sdBlockId: {
18824
- default: null,
18825
- keepOnSplit: false,
18826
- parseDOM: (elem) => elem.getAttribute("data-sd-block-id"),
18827
- renderDOM: (attrs) => {
18828
- return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
18829
- }
18830
- },
18831
- syncId: {
18832
- default: null,
18833
- parseDOM: (elem) => elem.getAttribute("data-sync-id"),
18834
- renderDOM: (attrs) => {
18835
- if (!attrs.syncId) return {};
18836
- return {
18837
- "data-sync-id": attrs.syncId
18838
- };
18839
- }
18840
- // rendered: false,
18841
- },
18842
- listId: {
18843
- keepOnSplit: true,
18844
- parseDOM: (elem) => elem.getAttribute("data-list-id"),
18845
- renderDOM: (attrs) => {
18846
- if (!attrs.listId) return {};
18847
- return {
18848
- "data-list-id": attrs.listId
18849
- };
18850
- }
18851
- },
18852
- "list-style-type": {
18853
- default: "decimal",
18854
- rendered: false
18855
- },
18856
- attributes: {
18857
- rendered: false,
18858
- keepOnSplit: true
18859
- }
18860
- };
18861
- },
18862
- parseDOM() {
18863
- return [{ tag: "ol" }];
18864
- },
18865
- renderDOM({ htmlAttributes }) {
18866
- const { start: start2, ...restAttributes } = htmlAttributes;
18867
- return start2 === 1 ? ["ol", Attribute.mergeAttributes(this.options.htmlAttributes, restAttributes), 0] : ["ol", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
18868
- },
18869
- addCommands() {
18870
- return {
18871
- /**
18872
- * Toggle ordered list formatting
18873
- * @category Command
18874
- * @example
18875
- * editor.commands.toggleOrderedList()
18876
- * @note Converts selection to ordered list or back to paragraphs
18877
- */
18878
- toggleOrderedList: () => (params2) => {
18879
- return toggleList(this.type)(params2);
18880
- },
18881
- /**
18882
- * Restart list node numbering
18883
- * @category Command
18884
- * @param {Array} followingNodes - Nodes to restart
18885
- * @param {number} pos - Starting position
18886
- * @example
18887
- * editor.commands.restartListNodes(nodes, position)
18888
- * @note Resets list numbering for specified nodes
18889
- */
18890
- restartListNodes: (followingNodes, pos) => ({ tr }) => {
18891
- let currentNodePos = pos;
18892
- const nodes = followingNodes.map((node) => {
18893
- const resultNode = {
18894
- node,
18895
- pos: currentNodePos
18896
- };
18897
- currentNodePos += node.nodeSize;
18898
- return resultNode;
18899
- });
18900
- nodes.forEach((item) => {
18901
- const { pos: pos2 } = item;
18902
- const newPos = tr.mapping.map(pos2);
18903
- tr.setNodeMarkup(newPos, void 0, {});
18904
- });
18905
- return true;
18906
- },
18907
- /**
18908
- * Update ordered list style type based on nesting level
18909
- * @category Command
18910
- * @example
18911
- * editor.commands.updateOrderedListStyleType()
18912
- * @note Cycles through decimal -> lowerAlpha -> lowerRoman based on depth
18913
- */
18914
- updateOrderedListStyleType: () => ({ dispatch, tr }) => {
18915
- let list = findParentNode((node) => node.type.name === this.name)(tr.selection);
18916
- if (!list) {
18917
- return true;
18918
- }
18919
- if (dispatch) {
18920
- let listLevel = (list.depth - 1) / 2;
18921
- let listStyleTypes = this.options.listStyleTypes;
18922
- let listStyle = listStyleTypes[listLevel % listStyleTypes.length];
18923
- let currentListStyle = list.node.attrs["list-style-type"];
18924
- let nodeAtPos = tr.doc.nodeAt(list.pos);
18925
- if (currentListStyle !== listStyle && nodeAtPos.eq(list.node)) {
18926
- tr.setNodeMarkup(list.pos, void 0, {
18927
- ...list.node.attrs,
18928
- ...{
18929
- "list-style-type": listStyle
18930
- }
18931
- });
18932
- }
18933
- }
18934
- return true;
18935
- }
18936
- };
18937
- },
18938
- addShortcuts() {
18939
- return {
18940
- "Mod-Shift-7": () => {
18941
- return this.editor.commands.toggleOrderedList();
18942
- }
18943
- };
18944
- },
18945
- addInputRules() {
18946
- return [
18947
- new InputRule({
18948
- match: inputRegex,
18949
- handler: ({ state, range }) => {
18950
- const $pos = state.selection.$from;
18951
- const listItemType = state.schema.nodes.listItem;
18952
- for (let depth = $pos.depth; depth >= 0; depth--) {
18953
- if ($pos.node(depth).type === listItemType) {
18954
- return null;
18955
- }
18956
- }
18957
- const { tr } = state;
18958
- tr.delete(range.from, range.to);
18959
- ListHelpers.createNewList({
18960
- listType: this.type,
18961
- tr,
18962
- editor: this.editor
18963
- });
18964
- }
18965
- })
18966
- ];
18967
- }
18968
- });
18969
- const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
18970
- const handler = listIndexMap[listNumberingType];
18971
- return handler ? handler(listLevel, lvlText, customFormat) : null;
18972
- };
18973
- const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
18974
- const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
18975
- const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
18976
- const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
18977
- const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
18978
- const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
18979
- const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
18980
- const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
18981
- const listIndexMap = {
18982
- decimal: handleDecimal,
18983
- lowerRoman: handleLowerRoman,
18984
- upperRoman: handleRoman,
18985
- lowerLetter: handleLowerAlpha,
18986
- upperLetter: handleAlpha,
18987
- ordinal: handleOrdinal,
18988
- custom: handleCustom,
18989
- japaneseCounting: handleJapaneseCounting
18990
- };
18991
- const createNumbering = (values, lvlText) => {
18992
- return values.reduce((acc, value, index2) => {
18993
- return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
18994
- }, lvlText);
18995
- };
18996
- const generateNumbering = (path, lvlText, formatter) => {
18997
- const formattedValues = path.map(formatter);
18998
- return createNumbering(formattedValues, lvlText);
18999
- };
19000
- const ordinalFormatter = (level) => {
19001
- const suffixes = ["th", "st", "nd", "rd"];
19002
- const value = level % 100;
19003
- const suffix = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
19004
- const p = level + suffix;
19005
- return p;
19006
- };
19007
- const generateFromCustom = (path, lvlText, customFormat) => {
19008
- if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
19009
- const match = customFormat.match(/(\d+)/);
19010
- if (!match) throw new Error("Invalid format string: no numeric pattern found");
19011
- const sample = match[1];
19012
- const digitCount = sample.length;
19013
- const index2 = path.pop();
19014
- return String(index2).padStart(digitCount, "0");
19015
- };
19016
- const intToRoman = (num) => {
19017
- const romanNumeralMap = [
19018
- { value: 1e3, numeral: "M" },
19019
- { value: 900, numeral: "CM" },
19020
- { value: 500, numeral: "D" },
19021
- { value: 400, numeral: "CD" },
19022
- { value: 100, numeral: "C" },
19023
- { value: 90, numeral: "XC" },
19024
- { value: 50, numeral: "L" },
19025
- { value: 40, numeral: "XL" },
19026
- { value: 10, numeral: "X" },
19027
- { value: 9, numeral: "IX" },
19028
- { value: 5, numeral: "V" },
19029
- { value: 4, numeral: "IV" },
19030
- { value: 1, numeral: "I" }
19031
- ];
19032
- let result = "";
19033
- for (const { value, numeral } of romanNumeralMap) {
19034
- while (num >= value) {
19035
- result += numeral;
19036
- num -= value;
19037
- }
19038
- }
19039
- return result;
19040
- };
19041
- const intToAlpha = (num) => {
19042
- let result = "";
19043
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
19044
- while (num > 0) {
19045
- let index2 = (num - 1) % 26;
19046
- result = alphabet[index2] + result;
19047
- num = Math.floor((num - 1) / 26);
19048
- }
19049
- return result;
19050
- };
19051
- const intToJapaneseCounting = (num) => {
19052
- const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
19053
- const units = ["", "十", "百", "千"];
19054
- if (num === 0) return "零";
19055
- if (num < 10) return digits[num];
19056
- let result = "";
19057
- let tempNum = num;
19058
- let unitIndex = 0;
19059
- while (tempNum > 0) {
19060
- const digit = tempNum % 10;
19061
- if (digit !== 0) {
19062
- const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
19063
- result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
19064
- } else if (result && tempNum > 0) {
19065
- if (!result.startsWith("零") && tempNum % 100 !== 0) {
19066
- result = "零" + result;
19067
- }
19068
- }
19069
- tempNum = Math.floor(tempNum / 10);
19070
- unitIndex++;
19071
- if (unitIndex > 3) break;
19072
- }
19073
- if (num >= 10 && num < 20) {
19074
- result = result.replace(/^一十/, "十");
19075
- }
19076
- return result;
19077
- };
19078
17860
  const isKeyboardInvocation = (event) => {
19079
17861
  return event.type === "contextmenu" && typeof event.detail === "number" && event.detail === 0 && (event.button === 0 || event.button === void 0) && event.clientX === 0 && event.clientY === 0;
19080
17862
  };
@@ -19363,16 +18145,22 @@ const getLinkedStyle = (styleId, styles = []) => {
19363
18145
  return { linkedStyle, basedOnStyle };
19364
18146
  };
19365
18147
  const getSpacingStyle = (spacing) => {
19366
- const { lineSpaceBefore, lineSpaceAfter, line, lineRule } = spacing;
18148
+ const { lineSpaceBefore, lineSpaceAfter, line, lineRule, beforeAutoSpacing, afterAutoSpacing } = spacing;
19367
18149
  const lineHeightResult = getLineHeightValueString(line, "", lineRule, true);
19368
18150
  const lineHeightStyles = typeof lineHeightResult === "object" && lineHeightResult !== null ? lineHeightResult : {};
18151
+ const result = {};
18152
+ if (!beforeAutoSpacing) {
18153
+ result["margin-top"] = lineSpaceBefore + "px";
18154
+ }
18155
+ if (!afterAutoSpacing) {
18156
+ result["margin-bottom"] = lineSpaceAfter + "px";
18157
+ }
19369
18158
  return {
19370
- "margin-top": lineSpaceBefore + "px",
19371
- "margin-bottom": lineSpaceAfter + "px",
18159
+ ...result,
19372
18160
  ...lineHeightStyles
19373
18161
  };
19374
18162
  };
19375
- const getSpacingStyleString = (spacing, marks) => {
18163
+ const getSpacingStyleString = (spacing, marks, isListItem) => {
19376
18164
  let { before, after, line, lineRule, beforeAutospacing, afterAutospacing } = spacing;
19377
18165
  line = twipsToLines(line);
19378
18166
  if (lineRule === "exact" && line) {
@@ -19381,12 +18169,22 @@ const getSpacingStyleString = (spacing, marks) => {
19381
18169
  const textStyleMark = marks?.find((mark) => mark.type === "textStyle");
19382
18170
  const fontSize = textStyleMark?.attrs?.fontSize;
19383
18171
  before = twipsToPixels(before);
19384
- if (beforeAutospacing && fontSize) {
19385
- before += halfPointToPixels(parseInt(fontSize) * 0.5);
18172
+ if (beforeAutospacing) {
18173
+ if (fontSize) {
18174
+ before += halfPointToPixels(parseInt(fontSize) * 0.5);
18175
+ }
18176
+ if (isListItem) {
18177
+ before = 0;
18178
+ }
19386
18179
  }
19387
18180
  after = twipsToPixels(after);
19388
- if (afterAutospacing && fontSize) {
19389
- after += halfPointToPixels(parseInt(fontSize) * 0.5);
18181
+ if (afterAutospacing) {
18182
+ if (fontSize) {
18183
+ after += halfPointToPixels(parseInt(fontSize) * 0.5);
18184
+ }
18185
+ if (isListItem) {
18186
+ after = 0;
18187
+ }
19390
18188
  }
19391
18189
  return `
19392
18190
  ${before ? `margin-top: ${before}px;` : ""}
@@ -19888,850 +18686,1047 @@ const LinkedStyles = Extension.create({
19888
18686
  };
19889
18687
  }
19890
18688
  });
19891
- function getUnderlineCssString({ type = "single", color = null, thickness = null, approximate = true } = {}) {
19892
- const parts = [];
19893
- const add = (k2, v) => {
19894
- if (!v) return;
19895
- parts.push(`${k2}: ${v}`);
19896
- };
19897
- const lower = String(type || "single").toLowerCase();
19898
- if (lower === "none" || lower === "0") {
19899
- add("text-decoration", "none");
19900
- return parts.join("; ");
19901
- }
19902
- add("text-decoration-line", "underline");
19903
- const HEAVY = thickness || "0.2em";
19904
- const THICK = thickness || "0.15em";
19905
- switch (lower) {
19906
- case "single":
19907
- break;
19908
- case "double":
19909
- add("text-decoration-style", "double");
19910
- break;
19911
- case "thick":
19912
- add("text-decoration-thickness", THICK);
19913
- break;
19914
- case "dotted":
19915
- add("text-decoration-style", "dotted");
19916
- break;
19917
- case "dash":
19918
- case "dashed":
19919
- add("text-decoration-style", "dashed");
19920
- break;
19921
- case "dotdash":
19922
- case "dotdotdash":
19923
- case "dashlong":
19924
- case "dashlongheavy":
19925
- if (approximate) {
19926
- add("text-decoration-style", "dashed");
19927
- if (lower.includes("heavy")) add("text-decoration-thickness", HEAVY);
18689
+ const getDefaultSpacing = () => ({
18690
+ after: null,
18691
+ before: null,
18692
+ line: null,
18693
+ lineRule: "auto"
18694
+ });
18695
+ const restartNumbering = ({ editor, tr, state, dispatch }) => {
18696
+ const { node: paragraph, pos } = findParentNode(isList)(state.selection) || {};
18697
+ if (!paragraph) return false;
18698
+ const allParagraphs = [{ node: paragraph, pos }];
18699
+ const startPos = pos + paragraph.nodeSize;
18700
+ const myNumId = paragraph.attrs.numberingProperties.numId;
18701
+ let stop = false;
18702
+ state.doc.nodesBetween(startPos, state.doc.content.size, (node, nodePos) => {
18703
+ if (node.type.name === "paragraph") {
18704
+ if (isList(node) && node.attrs.paragraphProperties?.numberingProperties?.numId === myNumId) {
18705
+ allParagraphs.push({ node, pos: nodePos });
18706
+ } else {
18707
+ stop = true;
19928
18708
  }
19929
- break;
19930
- case "dottedheavy":
19931
- add("text-decoration-style", "dotted");
19932
- add("text-decoration-thickness", HEAVY);
19933
- break;
19934
- case "dashedheavy":
19935
- add("text-decoration-style", "dashed");
19936
- add("text-decoration-thickness", HEAVY);
19937
- break;
19938
- case "wavy":
19939
- add("text-decoration-style", "wavy");
19940
- break;
19941
- case "wavyheavy":
19942
- add("text-decoration-style", "wavy");
19943
- add("text-decoration-thickness", HEAVY);
19944
- break;
19945
- case "wavydouble":
19946
- if (approximate) {
19947
- add("text-decoration-style", "wavy");
19948
- add("text-decoration-thickness", HEAVY);
18709
+ return false;
18710
+ }
18711
+ return !stop;
18712
+ });
18713
+ const { numberingType } = paragraph.attrs.listRendering || {};
18714
+ const listType = numberingType === "bullet" ? "bulletList" : "orderedList";
18715
+ const numId = ListHelpers.getNewListId(editor);
18716
+ ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor });
18717
+ allParagraphs.forEach(({ node, pos: pos2 }) => {
18718
+ updateNumberingProperties(
18719
+ {
18720
+ ...node.attrs.numberingProperties,
18721
+ numId: Number(numId)
18722
+ },
18723
+ node,
18724
+ pos2,
18725
+ editor,
18726
+ tr
18727
+ );
18728
+ });
18729
+ if (dispatch) dispatch(tr);
18730
+ return true;
18731
+ };
18732
+ const defaultTabDistance = 48;
18733
+ const defaultLineLength = 816;
18734
+ const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
18735
+ const decorations = [];
18736
+ const paragraphCache = /* @__PURE__ */ new Map();
18737
+ const coordCache = /* @__PURE__ */ new Map();
18738
+ const domPosCache = /* @__PURE__ */ new Map();
18739
+ const end2 = to ?? doc2.content.size;
18740
+ doc2.nodesBetween(from2, end2, (node, pos) => {
18741
+ if (node.type.name !== "tab") return;
18742
+ const $pos = doc2.resolve(pos);
18743
+ const paragraphContext = findParagraphContext($pos, paragraphCache, helpers2);
18744
+ if (!paragraphContext) return;
18745
+ const blockParent2 = $pos.node(paragraphContext.paragraphDepth);
18746
+ const style = calculateTabStyle(node.nodeSize, view, pos, blockParent2, paragraphContext, coordCache, domPosCache);
18747
+ if (style) {
18748
+ decorations.push(
18749
+ Decoration.node(pos, pos + node.nodeSize, {
18750
+ style
18751
+ })
18752
+ );
18753
+ }
18754
+ });
18755
+ return decorations;
18756
+ };
18757
+ function calculateTabStyle(nodeSize2, view, pos, blockParent2, paragraphContext, coordCache = null, domPosCache = null) {
18758
+ let extraStyles = "";
18759
+ try {
18760
+ const { tabStops, flattened, positionMap, startPos } = paragraphContext;
18761
+ if (paragraphContext.indentWidth === void 0) {
18762
+ paragraphContext.indentWidth = getIndentWidth(view, startPos, paragraphContext.indent, coordCache, domPosCache);
18763
+ }
18764
+ if (paragraphContext.tabHeight === void 0) {
18765
+ paragraphContext.tabHeight = calcTabHeight(blockParent2);
18766
+ }
18767
+ const indentWidth = paragraphContext.indentWidth;
18768
+ const hanging = twipsToPixels(Number(paragraphContext.indent.hanging) || 0);
18769
+ if (hanging > 0) {
18770
+ tabStops.unshift({ val: "start", pos: indentWidth + hanging });
18771
+ }
18772
+ const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
18773
+ const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos, coordCache, domPosCache) + accumulatedTabWidth;
18774
+ let tabWidth;
18775
+ if (tabStops.length) {
18776
+ const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
18777
+ if (tabStop) {
18778
+ tabWidth = tabStop.pos - currentWidth;
18779
+ let val = tabStop.val;
18780
+ const aliases = { left: "start", right: "end" };
18781
+ if (aliases[val]) val = aliases[val];
18782
+ if (val === "center" || val === "end" || val === "right") {
18783
+ const entryIndex = positionMap.get(pos);
18784
+ if (entryIndex === void 0) return;
18785
+ const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
18786
+ const segmentStartPos = pos + nodeSize2;
18787
+ const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
18788
+ const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos, coordCache, domPosCache);
18789
+ tabWidth -= val === "center" ? segmentWidth / 2 : segmentWidth;
18790
+ } else if (val === "decimal" || val === "num") {
18791
+ const entryIndex = positionMap.get(pos);
18792
+ if (entryIndex === void 0) return;
18793
+ const breakChar = tabStop.decimalChar || ".";
18794
+ const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
18795
+ const integralWidth = decimalPos ? measureRangeWidth(view, pos + nodeSize2, decimalPos, coordCache, domPosCache) : measureRangeWidth(
18796
+ view,
18797
+ pos + nodeSize2,
18798
+ startPos + paragraphContext.paragraph.nodeSize - 1,
18799
+ coordCache,
18800
+ domPosCache
18801
+ );
18802
+ tabWidth -= integralWidth;
18803
+ }
18804
+ if (tabStop.leader) {
18805
+ const leaderStyles = {
18806
+ dot: "border-bottom: 1px dotted black;",
18807
+ heavy: "border-bottom: 2px solid black;",
18808
+ hyphen: "border-bottom: 1px solid black;",
18809
+ middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
18810
+ underscore: "border-bottom: 1px solid black;"
18811
+ };
18812
+ extraStyles += leaderStyles[tabStop.leader] || "";
18813
+ }
19949
18814
  }
19950
- break;
18815
+ }
18816
+ if (!tabWidth || tabWidth < 1) {
18817
+ tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
18818
+ if (tabWidth === 0) tabWidth = defaultTabDistance;
18819
+ }
18820
+ const tabHeight = paragraphContext.tabHeight;
18821
+ paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
18822
+ return `width: ${tabWidth}px; height: ${tabHeight}; ${extraStyles}`;
18823
+ } catch (error) {
18824
+ console.error("tab decoration error", error);
19951
18825
  }
19952
- if (color) add("text-decoration-color", color);
19953
- return parts.join("; ");
19954
18826
  }
19955
- function collectTextStyleMarks(listItem, markType) {
19956
- const textStyleMarks = [];
19957
- const seenMarks = /* @__PURE__ */ new Set();
19958
- const attrs = {};
19959
- if (!markType) {
19960
- return {
19961
- marks: textStyleMarks,
19962
- attrs
19963
- };
18827
+ function findParagraphContext($pos, cache, helpers2) {
18828
+ for (let depth = $pos.depth; depth >= 0; depth--) {
18829
+ const node = $pos.node(depth);
18830
+ if (node?.type?.name === "paragraph") {
18831
+ const startPos = $pos.start(depth);
18832
+ if (!cache.has(startPos)) {
18833
+ const paragraphContext = extractParagraphContext(node, startPos, helpers2, depth);
18834
+ cache.set(startPos, paragraphContext);
18835
+ }
18836
+ return cache.get(startPos);
18837
+ }
18838
+ }
18839
+ return null;
18840
+ }
18841
+ function extractParagraphContext(node, startPos, helpers2, depth = 0) {
18842
+ let tabStops = [];
18843
+ if (Array.isArray(node.attrs?.tabStops)) {
18844
+ tabStops = node.attrs.tabStops.map((stop) => {
18845
+ const ref2 = stop?.tab;
18846
+ if (!ref2) return stop || null;
18847
+ return {
18848
+ val: ref2.tabType || "start",
18849
+ pos: twipsToPixels(Number(ref2.pos) || 0),
18850
+ leader: ref2.leader
18851
+ };
18852
+ }).filter(Boolean);
18853
+ } else {
18854
+ const style = helpers2.linkedStyles.getStyleById(node.attrs?.styleId);
18855
+ if (Array.isArray(style?.definition?.styles?.tabStops)) {
18856
+ tabStops = style.definition.styles.tabStops;
18857
+ }
19964
18858
  }
19965
- const collectMarks = (node) => {
18859
+ const { entries, positionMap } = flattenParagraph(node, startPos);
18860
+ return {
18861
+ paragraph: node,
18862
+ paragraphDepth: depth,
18863
+ startPos,
18864
+ indent: node.attrs?.indent || {},
18865
+ tabStops,
18866
+ flattened: entries,
18867
+ positionMap,
18868
+ // Store position map for O(1) lookups
18869
+ accumulatedTabWidth: 0
18870
+ };
18871
+ }
18872
+ function flattenParagraph(paragraph, paragraphStartPos) {
18873
+ const entries = [];
18874
+ const positionMap = /* @__PURE__ */ new Map();
18875
+ const walk = (node, basePos) => {
19966
18876
  if (!node) return;
19967
- const candidateMarks = Array.isArray(node.marks) ? node.marks : [];
19968
- if (candidateMarks.length && typeof markType.isInSet === "function" && markType.isInSet(candidateMarks)) {
19969
- candidateMarks.forEach((mark) => {
19970
- if (mark.type === markType && !seenMarks.has(mark)) {
19971
- seenMarks.add(mark);
19972
- textStyleMarks.push(mark);
19973
- }
18877
+ if (node.type?.name === "run") {
18878
+ node.forEach((child, offset2) => {
18879
+ const childPos = basePos + offset2 + 1;
18880
+ walk(child, childPos);
19974
18881
  });
18882
+ return;
19975
18883
  }
19976
- if (!node.isText && node.childCount) {
19977
- node.forEach((child) => collectMarks(child));
19978
- }
18884
+ const pos = basePos - 1;
18885
+ const index2 = entries.length;
18886
+ entries.push({ node, pos });
18887
+ positionMap.set(pos, index2);
19979
18888
  };
19980
- listItem.forEach((childNode) => {
19981
- if (childNode.type?.name !== "paragraph") return;
19982
- if (childNode.attrs?.lineHeight !== void 0) {
19983
- attrs.lineHeight = childNode.attrs.lineHeight;
19984
- }
19985
- collectMarks(childNode);
18889
+ paragraph.forEach((child, offset2) => {
18890
+ const childPos = paragraphStartPos + offset2 + 1;
18891
+ walk(child, childPos);
19986
18892
  });
19987
- return {
19988
- marks: textStyleMarks,
19989
- attrs
19990
- };
19991
- }
19992
- function parseSizeFromRunProperties(listRunProperties) {
19993
- const val = listRunProperties?.["w:val"] || listRunProperties?.["w:sz"];
19994
- if (val == null) return null;
19995
- const numeric = Number(val);
19996
- if (Number.isNaN(numeric) || numeric <= 0) return null;
19997
- const sizeInPoints = numeric / 2;
19998
- return `${sizeInPoints}pt`;
19999
- }
20000
- function parseFontFamilyFromRunProperties(listRunProperties) {
20001
- const ascii = listRunProperties?.["w:ascii"];
20002
- const hAnsi = listRunProperties?.["w:hAnsi"];
20003
- const eastAsia = listRunProperties?.["w:eastAsia"];
20004
- return ascii || hAnsi || eastAsia || null;
20005
- }
20006
- const computedStylesCache = /* @__PURE__ */ new WeakMap();
20007
- function clearComputedStyleCache(domNode) {
20008
- if (domNode) {
20009
- computedStylesCache.delete(domNode);
20010
- }
18893
+ return { entries, positionMap };
20011
18894
  }
20012
- function readNodeViewStyles(view) {
20013
- const fallback = { fontSize: null, fontFamily: null, lineHeight: null };
20014
- if (!view?.dom) return fallback;
20015
- const inline = {
20016
- fontSize: view.dom.style?.fontSize || null,
20017
- fontFamily: view.dom.style?.fontFamily || null,
20018
- lineHeight: view.dom.style?.lineHeight || null
20019
- };
20020
- if (inline.fontSize && inline.fontFamily && inline.lineHeight) return inline;
20021
- if (computedStylesCache.has(view.dom)) {
20022
- const cached = computedStylesCache.get(view.dom);
20023
- return {
20024
- fontSize: inline.fontSize || cached.fontSize,
20025
- fontFamily: inline.fontFamily || cached.fontFamily,
20026
- lineHeight: inline.lineHeight || cached.lineHeight
20027
- };
20028
- }
20029
- const globalWindow = typeof window !== "undefined" ? window : void 0;
20030
- if (globalWindow?.getComputedStyle) {
20031
- const computed2 = globalWindow.getComputedStyle(view.dom);
20032
- const computedStyles = {
20033
- fontSize: computed2.fontSize,
20034
- fontFamily: computed2.fontFamily,
20035
- lineHeight: computed2.lineHeight
20036
- };
20037
- computedStylesCache.set(view.dom, computedStyles);
20038
- return {
20039
- fontSize: inline.fontSize || computedStyles.fontSize,
20040
- fontFamily: inline.fontFamily || computedStyles.fontFamily,
20041
- lineHeight: inline.lineHeight || computedStyles.lineHeight
20042
- };
18895
+ function findNextTabIndex(flattened, fromIndex) {
18896
+ for (let i = fromIndex; i < flattened.length; i++) {
18897
+ if (flattened[i]?.node?.type?.name === "tab") {
18898
+ return i;
18899
+ }
20043
18900
  }
20044
- return inline;
18901
+ return -1;
20045
18902
  }
20046
- function getAdjacentListItemNodeView({ nodeView, pos, direction, activeNodeViews }) {
20047
- if (!activeNodeViews) return null;
20048
- let candidate = null;
20049
- activeNodeViews.forEach((view) => {
20050
- if (view === nodeView) return;
20051
- let viewPos;
20052
- try {
20053
- if (typeof view.getResolvedPos === "function") {
20054
- viewPos = view.getResolvedPos();
20055
- } else if (typeof view.getPos === "function") {
20056
- viewPos = view.getPos();
18903
+ function findDecimalBreakPos(flattened, startIndex, breakChar) {
18904
+ for (let i = startIndex; i < flattened.length; i++) {
18905
+ const entry = flattened[i];
18906
+ if (!entry) break;
18907
+ if (entry.node.type?.name === "tab") break;
18908
+ if (entry.node.type?.name === "text") {
18909
+ const index2 = entry.node.text?.indexOf(breakChar);
18910
+ if (index2 !== void 0 && index2 !== -1) {
18911
+ return entry.pos + index2 + 1;
20057
18912
  }
20058
- } catch {
20059
- return;
20060
- }
20061
- if (typeof viewPos !== "number") return;
20062
- if (viewPos < pos) {
20063
- if (!candidate || viewPos > candidate.pos) candidate = { view, pos: viewPos };
20064
- }
20065
- });
20066
- return candidate?.view ?? null;
20067
- }
20068
- function findSiblingListItem({ editor, pos, direction }) {
20069
- if (typeof pos !== "number" || !editor?.view) return null;
20070
- const { state } = editor.view;
20071
- const $pos = state.doc.resolve(pos);
20072
- const parentDepth = $pos.depth - 1;
20073
- if (parentDepth < 0) return null;
20074
- const parent = $pos.node(parentDepth);
20075
- if (!parent) return null;
20076
- const indexInsideParent = $pos.index(parentDepth);
20077
- const siblingIndex = indexInsideParent + direction;
20078
- if (siblingIndex < 0 || siblingIndex >= parent.childCount) return null;
20079
- const sibling = parent.child(siblingIndex);
20080
- return sibling?.type?.name === "listItem" ? sibling : null;
20081
- }
20082
- function deriveFontStylesFromNode({ node, textStyleType, defaultFont, defaultSize, listRunProperties }) {
20083
- const { marks: allMarks, attrs } = collectTextStyleMarks(node, textStyleType);
20084
- const styleMarks = textStyleType ? allMarks.filter((m) => m.type === textStyleType) : [];
20085
- const sizeMark = styleMarks.find((m) => m.attrs?.fontSize);
20086
- const familyMark = styleMarks.find((m) => m.attrs?.fontFamily);
20087
- let fontSize = defaultSize;
20088
- if (sizeMark) {
20089
- const [value, unit = "pt"] = parseSizeUnit(sizeMark.attrs.fontSize);
20090
- if (!Number.isNaN(value)) {
20091
- fontSize = `${value}${unit}`;
20092
- }
20093
- }
20094
- let hasSize = Boolean(sizeMark);
20095
- if (!hasSize && listRunProperties) {
20096
- const sizeFromList = parseSizeFromRunProperties(listRunProperties);
20097
- if (sizeFromList) {
20098
- fontSize = sizeFromList;
20099
- hasSize = true;
20100
- }
20101
- }
20102
- let fontFamily = familyMark?.attrs?.fontFamily ?? defaultFont;
20103
- let hasFamily = Boolean(familyMark);
20104
- if (!hasFamily && listRunProperties) {
20105
- const fontFromList = parseFontFamilyFromRunProperties(listRunProperties);
20106
- if (fontFromList) {
20107
- fontFamily = fontFromList;
20108
- hasFamily = true;
20109
- }
20110
- }
20111
- let lineHeight = attrs.lineHeight;
20112
- const firstChild = node.firstChild;
20113
- const hasOnlyOnePar = node.childCount === 1 && firstChild?.type?.name === "paragraph";
20114
- if (hasOnlyOnePar) {
20115
- const par = firstChild;
20116
- const parFirstChild = par?.firstChild;
20117
- if (par?.childCount === 1 && parFirstChild?.type?.name === "fieldAnnotation") {
20118
- const aFontSize = parFirstChild.attrs?.fontSize;
20119
- const aFontFamily = parFirstChild.attrs?.fontFamily;
20120
- if (!sizeMark && aFontSize) fontSize = aFontSize;
20121
- if (!familyMark && aFontFamily) fontFamily = aFontFamily;
20122
18913
  }
20123
18914
  }
20124
- return {
20125
- fontSize,
20126
- fontFamily,
20127
- lineHeight,
20128
- hasSize,
20129
- hasFamily
20130
- };
18915
+ return null;
20131
18916
  }
20132
- function getStylesFromLinkedStyles({ node, pos, editor }) {
20133
- const { state } = editor.view;
20134
- const linkedStyles = LinkedStylesPluginKey.getState(state)?.decorations;
20135
- const decorationsInPlace = linkedStyles?.find(pos, pos + node.nodeSize);
20136
- const predicates = [
20137
- (style2) => style2.includes("font-size") && style2.includes("font-family"),
20138
- (style2) => style2.includes("font-size"),
20139
- (style2) => style2.includes("font-family")
20140
- ];
20141
- let styleDeco;
20142
- for (const predicateFn of predicates) {
20143
- styleDeco = decorationsInPlace?.find((dec) => {
20144
- const style2 = dec.type?.attrs?.style || "";
20145
- return style2 && predicateFn(style2);
20146
- });
20147
- if (styleDeco) break;
18917
+ function measureRangeWidth(view, from2, to, coordCache = null, domPosCache = null) {
18918
+ if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
18919
+ try {
18920
+ const range = document.createRange();
18921
+ const fromRef = getCachedDomAtPos(view, from2, domPosCache);
18922
+ const toRef = getCachedDomAtPos(view, to, domPosCache);
18923
+ range.setStart(fromRef.node, fromRef.offset);
18924
+ range.setEnd(toRef.node, toRef.offset);
18925
+ const rect = range.getBoundingClientRect();
18926
+ range.detach?.();
18927
+ return rect.width || 0;
18928
+ } catch {
18929
+ const startLeft = getLeftCoord(view, from2, coordCache, domPosCache);
18930
+ const endLeft = getLeftCoord(view, to, coordCache, domPosCache);
18931
+ if (startLeft == null || endLeft == null) return 0;
18932
+ return Math.max(0, endLeft - startLeft);
20148
18933
  }
20149
- const style = styleDeco?.type?.attrs?.style;
20150
- const stylesArray = style?.split(";") || [];
20151
- const fontSizeFromStyles = stylesArray.find((s2) => s2.includes("font-size"))?.split(":")[1]?.trim();
20152
- const fontFamilyFromStyles = stylesArray.find((s2) => s2.includes("font-family"))?.split(":")[1]?.trim();
20153
- return {
20154
- font: fontFamilyFromStyles,
20155
- size: fontSizeFromStyles
20156
- };
20157
18934
  }
20158
- function resolveListItemTypography({ node, pos, editor, nodeView, activeNodeViews }) {
20159
- const defaults = getStylesFromLinkedStyles({ node, pos, editor });
20160
- const textStyleType = getMarkType("textStyle", editor.schema);
20161
- const currentStyles = deriveFontStylesFromNode({
20162
- node,
20163
- textStyleType,
20164
- defaultFont: defaults.font,
20165
- defaultSize: defaults.size,
20166
- listRunProperties: node.attrs?.listRunProperties
20167
- });
20168
- if ((!currentStyles.hasSize || !currentStyles.hasFamily || !currentStyles.lineHeight) && editor?.view) {
20169
- const previousListItem = findSiblingListItem({ editor, pos, direction: -1 });
20170
- if (previousListItem) {
20171
- const previousStyles = deriveFontStylesFromNode({
20172
- node: previousListItem,
20173
- textStyleType,
20174
- defaultFont: defaults.font,
20175
- defaultSize: defaults.size,
20176
- listRunProperties: previousListItem.attrs?.listRunProperties
20177
- });
20178
- if (!currentStyles.hasSize && previousStyles.fontSize) currentStyles.fontSize = previousStyles.fontSize;
20179
- if (!currentStyles.hasFamily && previousStyles.fontFamily) currentStyles.fontFamily = previousStyles.fontFamily;
20180
- if (!currentStyles.lineHeight && previousStyles.lineHeight) currentStyles.lineHeight = previousStyles.lineHeight;
18935
+ function getIndentWidth(view, paragraphStartPos, indentAttrs = {}, coordCache = null, domPosCache = null) {
18936
+ const marginLeft = getLeftCoord(view, paragraphStartPos, coordCache, domPosCache);
18937
+ const lineLeft = getLeftCoord(view, paragraphStartPos + 1, coordCache, domPosCache);
18938
+ if (marginLeft != null && lineLeft != null) {
18939
+ const diff = lineLeft - marginLeft;
18940
+ if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
18941
+ return diff;
20181
18942
  }
20182
18943
  }
20183
- if ((!currentStyles.fontSize || !currentStyles.fontFamily || !currentStyles.lineHeight) && nodeView) {
20184
- const previousView = getAdjacentListItemNodeView({
20185
- nodeView,
20186
- pos,
20187
- direction: -1,
20188
- activeNodeViews
20189
- });
20190
- if (previousView) {
20191
- const {
20192
- fontSize: prevSize,
20193
- fontFamily: prevFamily,
20194
- lineHeight: prevLineHeight
20195
- } = readNodeViewStyles(previousView);
20196
- if (!currentStyles.fontSize && prevSize) currentStyles.fontSize = prevSize;
20197
- if (!currentStyles.fontFamily && prevFamily) currentStyles.fontFamily = prevFamily;
20198
- if (!currentStyles.lineHeight && prevLineHeight) currentStyles.lineHeight = prevLineHeight;
20199
- }
18944
+ return calculateIndentFallback(indentAttrs);
18945
+ }
18946
+ function calculateIndentFallback(indentAttrs = {}) {
18947
+ if (!indentAttrs) return 0;
18948
+ const left2 = twipsToPixels(Number(indentAttrs.left) || 0);
18949
+ const firstLine = twipsToPixels(Number(indentAttrs.firstLine) || 0);
18950
+ const hanging = twipsToPixels(Number(indentAttrs.hanging) || 0);
18951
+ let textIndent = 0;
18952
+ if (firstLine && hanging) {
18953
+ textIndent = firstLine - hanging;
18954
+ } else if (firstLine) {
18955
+ textIndent = firstLine;
18956
+ } else if (hanging) {
18957
+ textIndent = -hanging;
20200
18958
  }
20201
- return {
20202
- fontSize: currentStyles.fontSize,
20203
- fontFamily: currentStyles.fontFamily,
20204
- lineHeight: currentStyles.lineHeight
20205
- };
18959
+ if (textIndent) return left2 + textIndent;
18960
+ if (left2) return left2;
18961
+ return 0;
20206
18962
  }
20207
- const MARKER_PADDING = 6;
20208
- const MARKER_OFFSET_RIGHT = 4;
20209
- const MIN_MARKER_WIDTH = 20;
20210
- const POINT_TO_PIXEL_CONVERSION_FACTOR = 1.33;
20211
- const DEFAULT_FONT_FAMILY = "Arial, sans-serif";
20212
- const DEFAULT_FONT_SIZE = "10pt";
20213
- const activeListItemNodeViews = /* @__PURE__ */ new Set();
20214
- class ListItemNodeView {
20215
- constructor(node, getPos, decorations, editor) {
20216
- __privateAdd(this, _ListItemNodeView_instances);
20217
- __publicField(this, "handleNumberingClick", () => {
20218
- });
20219
- this.node = node;
20220
- this.editor = editor;
20221
- this.decorations = decorations;
20222
- this.view = editor.view;
20223
- this._rawGetPos = getPos;
20224
- this._pendingIndentRefresh = null;
20225
- this.getPos = () => this.getResolvedPos();
20226
- __privateMethod(this, _ListItemNodeView_instances, init_fn3).call(this);
20227
- activeListItemNodeViews.add(this);
20228
- }
20229
- getResolvedPos() {
20230
- if (typeof this._rawGetPos !== "function") return null;
18963
+ function getLeftCoord(view, pos, coordCache = null, domPosCache = null) {
18964
+ if (!Number.isFinite(pos)) return null;
18965
+ if (coordCache && coordCache.has(pos)) {
18966
+ return coordCache.get(pos);
18967
+ }
18968
+ let result = null;
18969
+ try {
18970
+ result = view.coordsAtPos(pos).left;
18971
+ } catch {
20231
18972
  try {
20232
- const resolved = this._rawGetPos();
20233
- return typeof resolved === "number" ? resolved : null;
18973
+ const ref2 = getCachedDomAtPos(view, pos, domPosCache);
18974
+ const range = document.createRange();
18975
+ range.setStart(ref2.node, ref2.offset);
18976
+ range.setEnd(ref2.node, ref2.offset);
18977
+ const rect = range.getBoundingClientRect();
18978
+ range.detach?.();
18979
+ result = rect.left;
20234
18980
  } catch {
20235
- return null;
18981
+ result = null;
20236
18982
  }
20237
18983
  }
20238
- invalidateResolvedPos() {
18984
+ if (coordCache) {
18985
+ coordCache.set(pos, result);
20239
18986
  }
20240
- refreshIndentStyling({ immediate = false } = {}) {
20241
- const raf = typeof globalThis !== "undefined" ? globalThis.requestAnimationFrame : void 0;
20242
- const shouldSchedule = !immediate && typeof raf === "function";
20243
- if (!shouldSchedule) {
20244
- this._pendingIndentRefresh = null;
20245
- __privateMethod(this, _ListItemNodeView_instances, applyIndentStyling_fn).call(this);
20246
- return;
18987
+ return result;
18988
+ }
18989
+ function getCachedDomAtPos(view, pos, domPosCache = null) {
18990
+ if (domPosCache && domPosCache.has(pos)) {
18991
+ return domPosCache.get(pos);
18992
+ }
18993
+ const result = view.domAtPos(pos);
18994
+ if (domPosCache) {
18995
+ domPosCache.set(pos, result);
18996
+ }
18997
+ return result;
18998
+ }
18999
+ function calcTabHeight(blockParent2) {
19000
+ const ptToPxRatio = 1.333;
19001
+ const defaultFontSize = 16;
19002
+ const defaultLineHeight = 1.1;
19003
+ const parentTextStyleMark = blockParent2.firstChild?.marks?.find((mark) => mark.type.name === "textStyle");
19004
+ const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
19005
+ return `${fontSize * defaultLineHeight}px`;
19006
+ }
19007
+ class ParagraphNodeView {
19008
+ /**
19009
+ * @param {import('prosemirror-model').Node} node Current paragraph node.
19010
+ * @param {import('../../core/Editor').Editor} editor Editor instance providing schema/helpers.
19011
+ * @param {() => number} getPos Position getter provided by ProseMirror.
19012
+ * @param {import('prosemirror-view').Decoration[]} decorations Decorations applied to this node.
19013
+ * @param {Record<string, unknown>} extensionAttrs Extra attributes declared by the paragraph extension.
19014
+ */
19015
+ constructor(node, editor, getPos, decorations, extensionAttrs) {
19016
+ __privateAdd(this, _ParagraphNodeView_instances);
19017
+ this.node = node;
19018
+ this.editor = editor;
19019
+ this.getPos = getPos;
19020
+ this.decorations = decorations;
19021
+ this.extensionAttrs = extensionAttrs;
19022
+ this._animationFrameRequest = null;
19023
+ this.dom = document.createElement("p");
19024
+ this.contentDOM = document.createElement("span");
19025
+ this.dom.appendChild(this.contentDOM);
19026
+ if (__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
19027
+ __privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
19028
+ __privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
19029
+ if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
19030
+ return;
19031
+ }
19032
+ __privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
19033
+ });
20247
19034
  }
20248
- if (this._pendingIndentRefresh != null) return;
20249
- this._pendingIndentRefresh = raf(() => {
20250
- this._pendingIndentRefresh = null;
20251
- __privateMethod(this, _ListItemNodeView_instances, applyIndentStyling_fn).call(this);
20252
- });
19035
+ __privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
20253
19036
  }
19037
+ /**
19038
+ * @param {import('prosemirror-model').Node} node
19039
+ * @param {import('prosemirror-view').Decoration[]} decorations
19040
+ */
20254
19041
  update(node, decorations) {
20255
- const prevNode = this.node;
19042
+ const oldAttrs = this.node.attrs;
19043
+ const newAttrs = node.attrs;
20256
19044
  this.node = node;
20257
19045
  this.decorations = decorations;
20258
- this.invalidateResolvedPos();
20259
- const stylingAttrsChanged = !prevNode || prevNode.attrs.styleId !== node.attrs.styleId || prevNode.attrs.numId !== node.attrs.numId || prevNode.attrs.level !== node.attrs.level;
20260
- if (stylingAttrsChanged) {
20261
- clearComputedStyleCache(this.dom);
19046
+ if (JSON.stringify(oldAttrs) === JSON.stringify(newAttrs)) {
19047
+ return true;
20262
19048
  }
20263
- const { fontSize, fontFamily, lineHeight } = resolveListItemTypography({
20264
- node,
20265
- pos: this.getResolvedPos(),
20266
- editor: this.editor,
20267
- nodeView: this,
20268
- activeNodeViews: activeListItemNodeViews
19049
+ __privateMethod(this, _ParagraphNodeView_instances, updateHTMLAttributes_fn).call(this);
19050
+ if (!__privateMethod(this, _ParagraphNodeView_instances, checkIsList_fn).call(this)) {
19051
+ __privateMethod(this, _ParagraphNodeView_instances, removeList_fn).call(this);
19052
+ return true;
19053
+ }
19054
+ __privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
19055
+ __privateMethod(this, _ParagraphNodeView_instances, scheduleAnimation_fn).call(this, () => {
19056
+ __privateMethod(this, _ParagraphNodeView_instances, initList_fn).call(this, node.attrs.listRendering);
19057
+ __privateMethod(this, _ParagraphNodeView_instances, updateListStyles_fn).call(this);
20269
19058
  });
20270
- this.dom.style.fontSize = fontSize;
20271
- this.dom.style.fontFamily = fontFamily || "inherit";
20272
- this.dom.style.lineHeight = lineHeight || "";
20273
- const attrsChanged = stylingAttrsChanged || prevNode?.attrs.indent !== node.attrs.indent;
20274
- if (attrsChanged) {
20275
- this.refreshIndentStyling();
19059
+ return true;
19060
+ }
19061
+ /**
19062
+ * @param {MutationRecord} mutation
19063
+ */
19064
+ ignoreMutation(mutation) {
19065
+ if (this.marker && (mutation.target === this.marker || this.marker.contains(mutation.target))) {
19066
+ return true;
19067
+ }
19068
+ if (this.separator && (mutation.target === this.separator || this.separator.contains(mutation.target))) {
19069
+ return true;
19070
+ }
19071
+ if (mutation.type === "attributes" && mutation.target === this.dom && mutation.attributeName === "style") {
19072
+ return true;
20276
19073
  }
19074
+ return false;
20277
19075
  }
20278
19076
  destroy() {
20279
- activeListItemNodeViews.delete(this);
20280
- this.numberingDOM.removeEventListener("click", this.handleNumberingClick);
20281
- clearComputedStyleCache(this.dom);
20282
- const caf = typeof globalThis !== "undefined" ? globalThis.cancelAnimationFrame : void 0;
20283
- if (this._pendingIndentRefresh != null && typeof caf === "function") {
20284
- caf(this._pendingIndentRefresh);
20285
- }
20286
- this._pendingIndentRefresh = null;
19077
+ __privateMethod(this, _ParagraphNodeView_instances, cancelScheduledAnimation_fn).call(this);
20287
19078
  }
20288
19079
  }
20289
- _ListItemNodeView_instances = new WeakSet();
20290
- init_fn3 = function() {
20291
- const { attrs } = this.node;
20292
- const { listLevel, listNumberingType, lvlText, numId, level, customFormat } = attrs;
20293
- let orderMarker = "";
20294
- if (listLevel) {
20295
- if (listNumberingType !== "bullet") {
20296
- orderMarker = generateOrderedListIndex({
20297
- listLevel,
20298
- lvlText,
20299
- listNumberingType,
20300
- customFormat
20301
- });
20302
- } else {
20303
- orderMarker = docxNumberingHelpers.normalizeLvlTextChar(lvlText);
19080
+ _ParagraphNodeView_instances = new WeakSet();
19081
+ updateHTMLAttributes_fn = function() {
19082
+ const htmlAttributes = Attribute.getAttributesToRender(this.node, this.extensionAttrs);
19083
+ htmlAttributes.style = htmlAttributes.style || "";
19084
+ for (const [key2, value] of Object.entries(htmlAttributes || {})) {
19085
+ if (value == null) {
19086
+ this.dom.removeAttribute(key2);
19087
+ continue;
20304
19088
  }
19089
+ this.dom.setAttribute(key2, value);
20305
19090
  }
20306
- const pos = this.getResolvedPos();
20307
- const { fontSize, fontFamily, lineHeight } = resolveListItemTypography({
20308
- node: this.node,
20309
- pos,
20310
- editor: this.editor,
20311
- nodeView: this,
20312
- activeNodeViews: activeListItemNodeViews
19091
+ };
19092
+ updateListStyles_fn = function() {
19093
+ let { suffix, justification } = this.node.attrs.listRendering;
19094
+ suffix = suffix ?? "tab";
19095
+ __privateMethod(this, _ParagraphNodeView_instances, calculateMarkerStyle_fn).call(this, justification);
19096
+ if (suffix === "tab") {
19097
+ __privateMethod(this, _ParagraphNodeView_instances, calculateTabSeparatorStyle_fn).call(this, justification, this.node.attrs.indent);
19098
+ } else {
19099
+ this.separator.textContent = suffix === "space" ? " " : "";
19100
+ }
19101
+ return true;
19102
+ };
19103
+ /**
19104
+ * @param {{ markerText: string, suffix?: string }} listRendering
19105
+ */
19106
+ initList_fn = function(listRendering) {
19107
+ __privateMethod(this, _ParagraphNodeView_instances, createMarker_fn).call(this, listRendering.markerText);
19108
+ __privateMethod(this, _ParagraphNodeView_instances, createSeparator_fn).call(this, listRendering.suffix);
19109
+ };
19110
+ checkIsList_fn = function() {
19111
+ return isList(this.node);
19112
+ };
19113
+ /**
19114
+ * @param {string} markerText
19115
+ */
19116
+ createMarker_fn = function(markerText) {
19117
+ if (!this.marker) {
19118
+ this.marker = document.createElement("span");
19119
+ }
19120
+ this.marker.contentEditable = "false";
19121
+ this.marker.className = "list-marker";
19122
+ this.dom.insertBefore(this.marker, this.contentDOM);
19123
+ this.marker.textContent = markerText;
19124
+ };
19125
+ /**
19126
+ * @param {'tab' | 'space' | 'nothing'} [suffix]
19127
+ */
19128
+ createSeparator_fn = function(suffix) {
19129
+ if (suffix === "tab" || suffix == null) {
19130
+ if (this.separator == null || this.separator.tagName?.toLowerCase() !== "span") {
19131
+ this.separator?.parentNode?.removeChild(this.separator);
19132
+ this.separator = document.createElement("span");
19133
+ this.dom.insertBefore(this.separator, this.contentDOM);
19134
+ }
19135
+ this.separator.className = "sd-editor-tab";
19136
+ this.separator.contentEditable = "false";
19137
+ } else if (suffix === "space") {
19138
+ if (this.separator == null || this.separator.nodeType !== Node.TEXT_NODE) {
19139
+ this.separator?.parentNode?.removeChild(this.separator);
19140
+ this.separator = document.createTextNode(" ");
19141
+ this.dom.insertBefore(this.separator, this.contentDOM);
19142
+ }
19143
+ this.separator.textContent = " ";
19144
+ } else if (suffix === "nothing") {
19145
+ if (this.separator == null || this.separator.nodeType !== Node.TEXT_NODE) {
19146
+ this.separator?.parentNode?.removeChild(this.separator);
19147
+ this.separator = document.createTextNode("");
19148
+ this.dom.insertBefore(this.separator, this.contentDOM);
19149
+ }
19150
+ this.separator.textContent = "";
19151
+ }
19152
+ };
19153
+ /**
19154
+ * This is the logic behind the calculation:
19155
+ *
19156
+ * For left alignment:
19157
+ * - The tab character extends to the next tab stop
19158
+ *
19159
+ * For right alignment:
19160
+ * When: hanging is defined OR hanging is not defined and neither is firstLine
19161
+ * - The tab character extends to the hanging position only and never goes beyond it.
19162
+ *
19163
+ * When: firstLine is defined
19164
+ * - The tab character extends to the next tab stop
19165
+ *
19166
+ * For center alignment:
19167
+ * - The tab character extends to the next tab stop
19168
+ */
19169
+ /**
19170
+ * @param {'left' | 'right' | 'center'} justification
19171
+ * @param {{ hanging?: number, firstLine?: number } | null} indent
19172
+ */
19173
+ calculateTabSeparatorStyle_fn = function(justification, indent) {
19174
+ const markerWidth = this.marker.getBoundingClientRect().width;
19175
+ let tabStyle;
19176
+ let { paragraphContext, start: start2 } = __privateMethod(this, _ParagraphNodeView_instances, getParagraphContext_fn).call(this);
19177
+ if (justification === "right") {
19178
+ if (indent?.hanging || !indent?.hanging && !indent?.firstLine) {
19179
+ const hanging = indent?.hanging ? twipsToPixels(indent.hanging) : 0;
19180
+ tabStyle = `width: ${hanging}px;`;
19181
+ } else {
19182
+ const tabNode = this.editor.schema.nodes.tab.create(null);
19183
+ tabStyle = calculateTabStyle(tabNode.nodeSize, this.editor.view, start2, this.node, paragraphContext);
19184
+ }
19185
+ } else if (justification === "center") {
19186
+ paragraphContext.accumulatedTabWidth = markerWidth / 2;
19187
+ const tabNode = this.editor.schema.nodes.tab.create(null);
19188
+ tabStyle = calculateTabStyle(tabNode.nodeSize, this.editor.view, start2, this.node, paragraphContext);
19189
+ tabStyle += `margin-left: ${markerWidth / 2}px;`;
19190
+ } else {
19191
+ paragraphContext.accumulatedTabWidth = markerWidth;
19192
+ const tabNode = this.editor.schema.nodes.tab.create(null);
19193
+ tabStyle = calculateTabStyle(tabNode.nodeSize, this.editor.view, start2, this.node, paragraphContext);
19194
+ }
19195
+ this.separator.style.cssText = tabStyle;
19196
+ };
19197
+ /**
19198
+ * This is the logic behind the calculation:
19199
+ * For left alignment:
19200
+ * - The marker text STARTS at the left indent
19201
+ *
19202
+ * For right alignment:
19203
+ * - The marker text ENDS at the left indent
19204
+ *
19205
+ * For center alignment:
19206
+ * - The marker text is centered around the left indent (pulled back by half its width)
19207
+ *
19208
+ * The left/center/right alignment positioning uses the left indent (+ firstLine if present) as the anchor point.
19209
+ */
19210
+ /**
19211
+ * @param {'left' | 'right' | 'center'} justification
19212
+ */
19213
+ calculateMarkerStyle_fn = function(justification) {
19214
+ const runProperties = resolveRunProperties(
19215
+ { docx: this.editor.converter.convertedXml, numbering: this.editor.converter.numbering },
19216
+ this.node.attrs.paragraphProperties.runProperties || {},
19217
+ { ...this.node.attrs.paragraphProperties, numberingProperties: this.node.attrs.numberingProperties },
19218
+ true,
19219
+ Boolean(this.node.attrs.paragraphProperties.numberingProperties)
19220
+ );
19221
+ const style = encodeCSSFromRPr(runProperties, this.editor.converter.convertedXml);
19222
+ this.marker.style.cssText = Object.entries(style).map(([k2, v]) => `${k2}: ${v};`).join(" ");
19223
+ let markerStyle = {
19224
+ position: "",
19225
+ left: "",
19226
+ bottom: ""
19227
+ };
19228
+ let domStyle = {
19229
+ position: ""
19230
+ };
19231
+ const calculateTop = () => {
19232
+ let top2 = "0";
19233
+ if (globalThis) {
19234
+ const computedStyle = globalThis.getComputedStyle(this.dom);
19235
+ const markerComputedStyle = globalThis.getComputedStyle(this.marker);
19236
+ const lineHeight = parseFloat(computedStyle.lineHeight);
19237
+ const markerLineHeight = parseFloat(markerComputedStyle.lineHeight);
19238
+ top2 = `${lineHeight - markerLineHeight}px`;
19239
+ }
19240
+ return top2;
19241
+ };
19242
+ const rect = this.marker.getBoundingClientRect();
19243
+ const markerWidth = rect.width;
19244
+ if (justification === "right") {
19245
+ markerStyle.position = "absolute";
19246
+ markerStyle.left = `${-markerWidth}px`;
19247
+ markerStyle.top = calculateTop();
19248
+ domStyle.position = "relative";
19249
+ } else if (justification === "center") {
19250
+ markerStyle.position = "absolute";
19251
+ markerStyle.left = `${-markerWidth / 2}px`;
19252
+ markerStyle.top = calculateTop();
19253
+ domStyle.position = "relative";
19254
+ }
19255
+ Object.entries(markerStyle).forEach(([k2, v]) => {
19256
+ this.marker.style[k2] = v;
19257
+ });
19258
+ Object.entries(domStyle).forEach(([k2, v]) => {
19259
+ this.dom.style[k2] = v;
20313
19260
  });
20314
- this.dom = document.createElement("li");
20315
- this.dom.className = "sd-editor-list-item-node-view";
20316
- this.dom.style.fontSize = fontSize;
20317
- this.dom.style.fontFamily = fontFamily ? fontFamily : "inherit";
20318
- this.dom.style.lineHeight = lineHeight || "";
20319
- this.dom.setAttribute("data-marker-type", orderMarker);
20320
- this.dom.setAttribute("data-num-id", numId);
20321
- this.dom.setAttribute("data-list-level", JSON.stringify(listLevel));
20322
- this.dom.setAttribute("data-list-numbering-type", listNumberingType);
20323
- this.dom.setAttribute("data-level", level);
20324
- this.numberingDOM = document.createElement("span");
20325
- this.numberingDOM.className = "sd-editor-list-item-numbering";
20326
- this.numberingDOM.textContent = orderMarker;
20327
- this.numberingDOM.setAttribute("contenteditable", "false");
20328
- this.numberingDOM.addEventListener("click", this.handleNumberingClick);
20329
- this.contentDOM = document.createElement("div");
20330
- this.contentDOM.className = "sd-editor-list-item-content-dom";
20331
- this.dom.appendChild(this.numberingDOM);
20332
- this.dom.appendChild(this.contentDOM);
20333
- this.refreshIndentStyling({ immediate: true });
20334
19261
  };
20335
- applyIndentStyling_fn = function() {
20336
- const { attrs } = this.node;
20337
- const { styleId, numId, level, indent: inlineIndent } = attrs;
20338
- const defs = getListItemStyleDefinitions({ styleId, node: this.node, numId, level, editor: this.editor });
20339
- const visibleIndent = getVisibleIndent(defs.stylePpr, defs.numDefPpr, inlineIndent);
20340
- const lvlJc = defs.numLvlJs?.attributes?.["w:val"] || "left";
20341
- const contentLeft = visibleIndent.left || 0;
20342
- const hanging = visibleIndent.hanging || 0;
20343
- const handlers2 = {
20344
- right: () => {
20345
- const calculatedWidth = calculateMarkerWidth(this.dom, this.numberingDOM, this.editor);
20346
- const minMarkerWidth = Math.max(calculatedWidth, MIN_MARKER_WIDTH);
20347
- const effectiveHanging = Math.max(hanging, minMarkerWidth);
20348
- const markerLeft = contentLeft - effectiveHanging - MARKER_OFFSET_RIGHT;
20349
- this.contentDOM.style.marginLeft = `${contentLeft}px`;
20350
- this.numberingDOM.style.left = `${markerLeft}px`;
20351
- this.numberingDOM.style.width = `${effectiveHanging}px`;
20352
- this.numberingDOM.style.textAlign = "right";
19262
+ removeList_fn = function() {
19263
+ if (this.marker) {
19264
+ this.dom.removeChild(this.marker);
19265
+ this.marker = null;
19266
+ }
19267
+ if (this.separator) {
19268
+ this.dom.removeChild(this.separator);
19269
+ this.separator = null;
19270
+ }
19271
+ this.dom.style.position = "";
19272
+ };
19273
+ getParagraphContext_fn = function() {
19274
+ const $pos = this.editor.state.doc.resolve(this.getPos());
19275
+ const start2 = $pos.start($pos.depth + 1);
19276
+ const paragraphContext = extractParagraphContext(this.node, start2, this.editor.helpers);
19277
+ return { paragraphContext, start: start2 };
19278
+ };
19279
+ /**
19280
+ * @param {() => void} fn
19281
+ */
19282
+ scheduleAnimation_fn = function(fn2) {
19283
+ if (typeof globalThis === "undefined") {
19284
+ return;
19285
+ }
19286
+ __privateMethod(this, _ParagraphNodeView_instances, cancelScheduledAnimation_fn).call(this);
19287
+ this._animationFrameRequest = globalThis.requestAnimationFrame(() => {
19288
+ fn2();
19289
+ this._animationFrameRequest = null;
19290
+ });
19291
+ };
19292
+ cancelScheduledAnimation_fn = function() {
19293
+ if (typeof globalThis === "undefined" || !this._animationFrameRequest) {
19294
+ return;
19295
+ }
19296
+ globalThis.cancelAnimationFrame(this._animationFrameRequest);
19297
+ this._animationFrameRequest = null;
19298
+ };
19299
+ function NumberingManager() {
19300
+ let countersMap = {};
19301
+ let abstractCountersMap = {};
19302
+ let abstractIdMap = {};
19303
+ const startsMap = {};
19304
+ let lastSeenMap = {};
19305
+ let pathCache = {};
19306
+ let cacheEnabled = false;
19307
+ return {
19308
+ /**
19309
+ * Persist the base start value and optional restart limit for a given
19310
+ * numId/level combination.
19311
+ *
19312
+ * @param {string | number} numId
19313
+ * @param {number} level
19314
+ * @param {number} startValue
19315
+ * @param {number} [restartValue]
19316
+ */
19317
+ setStartSettings(numId, level, startValue, restartValue) {
19318
+ if (!startsMap[numId]) {
19319
+ startsMap[numId] = {};
19320
+ }
19321
+ if (!startsMap[numId][level]) {
19322
+ startsMap[numId][level] = {};
19323
+ }
19324
+ startsMap[numId][level].start = startValue;
19325
+ startsMap[numId][level].restart = restartValue;
19326
+ },
19327
+ /**
19328
+ * Record the computed counter for a specific node position. When caching is
19329
+ * enabled this also tracks the latest position to speed up lookups.
19330
+ *
19331
+ * @param {string | number} numId
19332
+ * @param {number} level
19333
+ * @param {number} pos
19334
+ * @param {number} value
19335
+ */
19336
+ setCounter(numId, level, pos, value, abstractId) {
19337
+ if (!countersMap[numId]) {
19338
+ countersMap[numId] = {};
19339
+ }
19340
+ if (!countersMap[numId][level]) {
19341
+ countersMap[numId][level] = {};
19342
+ }
19343
+ countersMap[numId][level][pos] = value;
19344
+ abstractIdMap[numId] = abstractId;
19345
+ if (!abstractCountersMap[abstractId]) {
19346
+ abstractCountersMap[abstractId] = {};
19347
+ }
19348
+ if (!abstractCountersMap[abstractId][level]) {
19349
+ abstractCountersMap[abstractId][level] = {};
19350
+ }
19351
+ abstractCountersMap[abstractId][level][pos] = value;
19352
+ if (!cacheEnabled) {
19353
+ return;
19354
+ }
19355
+ if (!lastSeenMap[numId]) {
19356
+ lastSeenMap[numId] = {};
19357
+ }
19358
+ const lastSeen = lastSeenMap[numId][level];
19359
+ if (!lastSeen || pos > lastSeen.pos) {
19360
+ lastSeenMap[numId][level] = { pos, count: value };
19361
+ }
19362
+ },
19363
+ /**
19364
+ * Retrieve a previously stored counter for the provided position.
19365
+ *
19366
+ * @param {string | number} numId
19367
+ * @param {number} level
19368
+ * @param {number} pos
19369
+ * @returns {number | null}
19370
+ */
19371
+ getCounter(numId, level, pos) {
19372
+ if (countersMap[numId] && countersMap[numId][level] && countersMap[numId][level][pos] != null) {
19373
+ return countersMap[numId][level][pos];
19374
+ }
19375
+ return null;
19376
+ },
19377
+ /**
19378
+ * Calculate the counter value that should be used for the given position,
19379
+ * respecting restart rules, ancestor usage, and cached history.
19380
+ *
19381
+ * @param {string | number} numId
19382
+ * @param {number} level
19383
+ * @param {number} pos
19384
+ * @returns {number}
19385
+ */
19386
+ calculateCounter(numId, level, pos, abstractId) {
19387
+ abstractIdMap[numId] = abstractId;
19388
+ const restartSetting = startsMap?.[numId]?.[level]?.restart;
19389
+ const startValue = startsMap?.[numId]?.[level]?.start ?? 1;
19390
+ const levelData = countersMap?.[numId]?.[level] || {};
19391
+ let previousPos = null;
19392
+ let previousCount = startValue - 1;
19393
+ if (cacheEnabled) {
19394
+ const cachedLast = lastSeenMap?.[numId]?.[level];
19395
+ if (cachedLast && cachedLast.pos < pos) {
19396
+ previousPos = cachedLast.pos;
19397
+ previousCount = cachedLast.count;
19398
+ }
19399
+ }
19400
+ if (previousPos == null) {
19401
+ const fallbackPos = Object.keys(levelData).map((p) => parseInt(p)).filter((p) => p < pos).pop();
19402
+ if (fallbackPos != null) {
19403
+ previousPos = fallbackPos;
19404
+ previousCount = levelData[fallbackPos];
19405
+ }
19406
+ }
19407
+ if (restartSetting === 0) {
19408
+ return previousCount + 1;
19409
+ }
19410
+ if (previousPos == null) {
19411
+ return startValue;
19412
+ }
19413
+ const usedLevels = [];
19414
+ for (let lvl = 0; lvl < level; lvl++) {
19415
+ const levelData2 = abstractCountersMap?.[abstractId]?.[lvl] || {};
19416
+ const hasUsed = Object.keys(levelData2).map((p) => parseInt(p)).some((p) => p > previousPos && p < pos);
19417
+ if (hasUsed) {
19418
+ usedLevels.push(lvl);
19419
+ }
19420
+ }
19421
+ if (usedLevels.length === 0) {
19422
+ return previousCount + 1;
19423
+ }
19424
+ if (restartSetting == null) {
19425
+ return startValue;
19426
+ }
19427
+ const shouldRestart = usedLevels.some((lvl) => lvl <= restartSetting);
19428
+ if (shouldRestart) {
19429
+ return startValue;
19430
+ }
19431
+ return previousCount + 1;
20353
19432
  },
20354
- left: () => {
20355
- const calculatedWidth = calculateMarkerWidth(this.dom, this.numberingDOM, this.editor);
20356
- const minMarkerWidth = Math.max(calculatedWidth, MIN_MARKER_WIDTH);
20357
- let markerLeft = contentLeft - hanging;
20358
- if (markerLeft === contentLeft) {
20359
- markerLeft -= minMarkerWidth;
20360
- } else if (minMarkerWidth > hanging) {
20361
- const diff = minMarkerWidth - hanging;
20362
- markerLeft -= diff;
20363
- }
20364
- this.contentDOM.style.marginLeft = `${contentLeft}px`;
20365
- this.numberingDOM.style.left = `${markerLeft}px`;
20366
- this.numberingDOM.style.width = "";
20367
- this.numberingDOM.style.textAlign = "";
19433
+ /**
19434
+ * Resolve the counter values for every ancestor level preceding the given
19435
+ * position. All numbering definitions that have the same abstract id
19436
+ * are considered. Results are cached when cache mode is active.
19437
+ *
19438
+ * @param {string | number} numId
19439
+ * @param {number} level
19440
+ * @param {number} pos
19441
+ * @returns {number[]}
19442
+ */
19443
+ getAncestorsPath(numId, level, pos) {
19444
+ if (cacheEnabled && pathCache?.[numId]?.[level]?.[pos]) {
19445
+ return pathCache[numId][level][pos];
19446
+ }
19447
+ const path = [];
19448
+ const abstractId = abstractIdMap[numId];
19449
+ for (let lvl = 0; lvl < level; lvl++) {
19450
+ const startCount = startsMap?.[numId]?.[lvl]?.start ?? 1;
19451
+ const levelData = abstractCountersMap?.[abstractId]?.[lvl] || {};
19452
+ if (levelData == null) {
19453
+ path.push(startCount);
19454
+ continue;
19455
+ }
19456
+ const previousPos = Object.keys(levelData).map((p) => parseInt(p)).filter((p) => p < pos).pop();
19457
+ if (previousPos == null) {
19458
+ path.push(startCount);
19459
+ } else {
19460
+ path.push(levelData[previousPos]);
19461
+ }
19462
+ }
19463
+ if (cacheEnabled) {
19464
+ if (!pathCache[numId]) {
19465
+ pathCache[numId] = {};
19466
+ }
19467
+ if (!pathCache[numId][level]) {
19468
+ pathCache[numId][level] = {};
19469
+ }
19470
+ pathCache[numId][level][pos] = path;
19471
+ }
19472
+ return path;
19473
+ },
19474
+ /**
19475
+ * Convenience helper that appends the current level counter on top of the
19476
+ * ancestor path.
19477
+ *
19478
+ * @param {string | number} numId
19479
+ * @param {number} level
19480
+ * @param {number} pos
19481
+ * @returns {number[]}
19482
+ */
19483
+ calculatePath(numId, level, pos) {
19484
+ const path = this.getAncestorsPath(numId, level, pos);
19485
+ const myCount = this.getCounter(numId, level, pos);
19486
+ path.push(myCount);
19487
+ return path;
19488
+ },
19489
+ /**
19490
+ * Expose the internal counters map mainly for debugging and tests.
19491
+ *
19492
+ * @returns {Record<string, Record<string, Record<string, number>>>}
19493
+ */
19494
+ getCountersMap() {
19495
+ return countersMap;
19496
+ },
19497
+ /**
19498
+ * Reset cached counter/path structures. Intended for internal use only.
19499
+ */
19500
+ _clearCache() {
19501
+ lastSeenMap = {};
19502
+ pathCache = {};
19503
+ countersMap = {};
19504
+ abstractCountersMap = {};
19505
+ abstractIdMap = {};
19506
+ },
19507
+ /**
19508
+ * Enable cache-aware logic (used during document scans) and drop stale data.
19509
+ */
19510
+ enableCache() {
19511
+ cacheEnabled = true;
19512
+ this._clearCache();
19513
+ },
19514
+ /**
19515
+ * Disable cache-aware logic and clear residual cache entries.
19516
+ */
19517
+ disableCache() {
19518
+ cacheEnabled = false;
19519
+ this._clearCache();
20368
19520
  }
20369
19521
  };
20370
- const handleStyles = handlers2[lvlJc] ?? handlers2.left;
20371
- handleStyles();
19522
+ }
19523
+ const generateOrderedListIndex = ({ listLevel, lvlText, listNumberingType, customFormat }) => {
19524
+ const handler = listIndexMap[listNumberingType];
19525
+ return handler ? handler(listLevel, lvlText, customFormat) : null;
20372
19526
  };
20373
- function refreshAllListItemNodeViews() {
20374
- activeListItemNodeViews.forEach((nodeView) => {
20375
- try {
20376
- nodeView.refreshIndentStyling({ immediate: true });
20377
- } catch (error) {
20378
- console.error("Error refreshing list item node view:", error);
20379
- activeListItemNodeViews.delete(nodeView);
19527
+ const handleDecimal = (path, lvlText) => generateNumbering(path, lvlText, String);
19528
+ const handleRoman = (path, lvlText) => generateNumbering(path, lvlText, intToRoman);
19529
+ const handleLowerRoman = (path, lvlText) => handleRoman(path, lvlText).toLowerCase();
19530
+ const handleLowerAlpha = (path, lvlText) => handleAlpha(path, lvlText).toLowerCase();
19531
+ const handleAlpha = (path, lvlText) => generateNumbering(path, lvlText, (p) => intToAlpha(p));
19532
+ const handleOrdinal = (path, lvlText) => generateNumbering(path, lvlText, ordinalFormatter);
19533
+ const handleCustom = (path, lvlText, customFormat) => generateFromCustom(path, lvlText, customFormat);
19534
+ const handleJapaneseCounting = (path, lvlText) => generateNumbering(path, lvlText, intToJapaneseCounting);
19535
+ const listIndexMap = {
19536
+ decimal: handleDecimal,
19537
+ lowerRoman: handleLowerRoman,
19538
+ upperRoman: handleRoman,
19539
+ lowerLetter: handleLowerAlpha,
19540
+ upperLetter: handleAlpha,
19541
+ ordinal: handleOrdinal,
19542
+ custom: handleCustom,
19543
+ japaneseCounting: handleJapaneseCounting
19544
+ };
19545
+ const createNumbering = (values, lvlText) => {
19546
+ return values.reduce((acc, value, index2) => {
19547
+ return value > 9 ? acc.replace(/^0/, "").replace(`%${index2 + 1}`, value) : acc.replace(`%${index2 + 1}`, value);
19548
+ }, lvlText);
19549
+ };
19550
+ const generateNumbering = (path, lvlText, formatter) => {
19551
+ const formattedValues = path.map(formatter);
19552
+ return createNumbering(formattedValues, lvlText);
19553
+ };
19554
+ const ordinalFormatter = (level) => {
19555
+ const suffixes = ["th", "st", "nd", "rd"];
19556
+ const value = level % 100;
19557
+ const suffix = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];
19558
+ const p = level + suffix;
19559
+ return p;
19560
+ };
19561
+ const generateFromCustom = (path, lvlText, customFormat) => {
19562
+ if (customFormat !== "001, 002, 003, ...") return generateNumbering(path, lvlText, String);
19563
+ const match = customFormat.match(/(\d+)/);
19564
+ if (!match) throw new Error("Invalid format string: no numeric pattern found");
19565
+ const sample = match[1];
19566
+ const digitCount = sample.length;
19567
+ const index2 = path.pop();
19568
+ return String(index2).padStart(digitCount, "0");
19569
+ };
19570
+ const intToRoman = (num) => {
19571
+ const romanNumeralMap = [
19572
+ { value: 1e3, numeral: "M" },
19573
+ { value: 900, numeral: "CM" },
19574
+ { value: 500, numeral: "D" },
19575
+ { value: 400, numeral: "CD" },
19576
+ { value: 100, numeral: "C" },
19577
+ { value: 90, numeral: "XC" },
19578
+ { value: 50, numeral: "L" },
19579
+ { value: 40, numeral: "XL" },
19580
+ { value: 10, numeral: "X" },
19581
+ { value: 9, numeral: "IX" },
19582
+ { value: 5, numeral: "V" },
19583
+ { value: 4, numeral: "IV" },
19584
+ { value: 1, numeral: "I" }
19585
+ ];
19586
+ let result = "";
19587
+ for (const { value, numeral } of romanNumeralMap) {
19588
+ while (num >= value) {
19589
+ result += numeral;
19590
+ num -= value;
20380
19591
  }
20381
- });
20382
- }
20383
- const getVisibleIndent = (stylePpr, numDefPpr, inlineIndent) => {
20384
- const styleIndentTag = stylePpr?.elements?.find((el) => el.name === "w:ind") || {};
20385
- const styleIndent = parseIndentElement(styleIndentTag);
20386
- const numDefIndentTag = numDefPpr?.elements?.find((el) => el.name === "w:ind") || {};
20387
- const numDefIndent = parseIndentElement(numDefIndentTag);
20388
- const indent = combineIndents(styleIndent, numDefIndent);
20389
- const result = combineIndents(indent, inlineIndent);
19592
+ }
20390
19593
  return result;
20391
19594
  };
20392
- function calculateMarkerWidth(dom, numberingDOM, editor, { withPadding = true } = {}) {
20393
- const markerText = numberingDOM.textContent || "";
20394
- const fontSize = dom.style.fontSize || DEFAULT_FONT_SIZE;
20395
- const fontValue = dom.style.fontFamily;
20396
- const fontFamily = fontValue && fontValue !== "inherit" ? fontValue : DEFAULT_FONT_FAMILY;
20397
- if (!markerText.trim()) return 0;
20398
- try {
20399
- if (editor?.options?.isHeadless) return 0;
20400
- if (typeof globalThis.CanvasRenderingContext2D === "undefined") return 0;
20401
- const canvas = document.createElement("canvas");
20402
- if (typeof canvas.getContext !== "function") return 0;
20403
- const context = canvas.getContext("2d");
20404
- if (!context) return 0;
20405
- const fontSizePx = fontSize.includes("pt") ? Number.parseFloat(fontSize) * POINT_TO_PIXEL_CONVERSION_FACTOR : Number.parseFloat(fontSize);
20406
- context.font = `${fontSizePx}px ${fontFamily}`;
20407
- const textWidth = context.measureText(markerText).width;
20408
- const resultWidth = withPadding ? Math.ceil(textWidth + MARKER_PADDING) : Math.ceil(textWidth);
20409
- return resultWidth;
20410
- } catch {
20411
- return 0;
19595
+ const intToAlpha = (num) => {
19596
+ let result = "";
19597
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
19598
+ while (num > 0) {
19599
+ let index2 = (num - 1) % 26;
19600
+ result = alphabet[index2] + result;
19601
+ num = Math.floor((num - 1) / 26);
19602
+ }
19603
+ return result;
19604
+ };
19605
+ const intToJapaneseCounting = (num) => {
19606
+ const digits = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
19607
+ const units = ["", "十", "百", "千"];
19608
+ if (num === 0) return "零";
19609
+ if (num < 10) return digits[num];
19610
+ let result = "";
19611
+ let tempNum = num;
19612
+ let unitIndex = 0;
19613
+ while (tempNum > 0) {
19614
+ const digit = tempNum % 10;
19615
+ if (digit !== 0) {
19616
+ const digitStr = digit === 1 && unitIndex > 0 ? "" : digits[digit];
19617
+ result = digitStr + (unitIndex > 0 ? units[unitIndex] : "") + result;
19618
+ } else if (result && tempNum > 0) {
19619
+ if (!result.startsWith("零") && tempNum % 100 !== 0) {
19620
+ result = "零" + result;
19621
+ }
19622
+ }
19623
+ tempNum = Math.floor(tempNum / 10);
19624
+ unitIndex++;
19625
+ if (unitIndex > 3) break;
19626
+ }
19627
+ if (num >= 10 && num < 20) {
19628
+ result = result.replace(/^一十/, "十");
19629
+ }
19630
+ return result;
19631
+ };
19632
+ function createNumberingPlugin(editor) {
19633
+ const numberingManager = NumberingManager();
19634
+ const applyStartSettingsFromDefinitions = (definitionsMap) => {
19635
+ Object.entries(definitionsMap || {}).forEach(([numId, levels]) => {
19636
+ Object.entries(levels || {}).forEach(([level, def]) => {
19637
+ const start2 = parseInt(def?.start) || 1;
19638
+ let restart = def?.restart;
19639
+ if (restart != null) {
19640
+ restart = parseInt(restart);
19641
+ }
19642
+ numberingManager.setStartSettings(numId, parseInt(level), start2, restart);
19643
+ });
19644
+ });
19645
+ };
19646
+ const refreshStartSettings = () => {
19647
+ const definitions = ListHelpers.getAllListDefinitions(editor);
19648
+ applyStartSettingsFromDefinitions(definitions);
19649
+ };
19650
+ refreshStartSettings();
19651
+ if (typeof editor?.on === "function") {
19652
+ editor.on("list-definitions-change", refreshStartSettings);
19653
+ if (typeof editor?.off === "function") {
19654
+ const cleanupListDefinitionListener = () => {
19655
+ editor.off("list-definitions-change", refreshStartSettings);
19656
+ editor.off?.("destroy", cleanupListDefinitionListener);
19657
+ };
19658
+ editor.on("destroy", cleanupListDefinitionListener);
19659
+ }
20412
19660
  }
20413
- }
20414
- const orderedListSyncPluginKey = new PluginKey("orderedListSync");
20415
- function orderedListSync(editor) {
20416
- let hasInitialized = false;
20417
- const docx = editor.converter.convertedXml;
20418
19661
  return new Plugin({
20419
- key: orderedListSyncPluginKey,
19662
+ name: "numberingPlugin",
19663
+ key: new PluginKey("numberingPlugin"),
19664
+ /**
19665
+ * Scan document changes and collect fresh numbering metadata for list
19666
+ * paragraphs. The incoming transactions are marked to avoid reprocessing.
19667
+ *
19668
+ * @param {import('prosemirror-state').Transaction[]} transactions
19669
+ * @param {import('prosemirror-state').EditorState} oldState
19670
+ * @param {import('prosemirror-state').EditorState} newState
19671
+ * @returns {import('prosemirror-state').Transaction | null}
19672
+ */
20420
19673
  appendTransaction(transactions, oldState, newState) {
20421
- if (transactions.every((tr2) => tr2.getMeta("y-sync$"))) return null;
20422
- const updateNodeViews = transactions.some((tr2) => tr2.getMeta("updatedListItemNodeViews"));
20423
- if (updateNodeViews || !hasInitialized) {
20424
- refreshAllListItemNodeViews();
20425
- }
20426
19674
  const isFromPlugin = transactions.some((tr2) => tr2.getMeta("orderedListSync"));
20427
- const docChanged = transactions.some((tr2) => tr2.docChanged) && !oldState.doc.eq(newState.doc);
20428
- if (isFromPlugin || !docChanged) {
19675
+ if (isFromPlugin || !transactions.some((tr2) => tr2.docChanged)) {
20429
19676
  return null;
20430
19677
  }
20431
- hasInitialized = true;
20432
19678
  const tr = newState.tr;
20433
19679
  tr.setMeta("orderedListSync", true);
20434
- const listMap = /* @__PURE__ */ new Map();
20435
- const listInitialized = /* @__PURE__ */ new Map();
20436
- const shouldProcess = transactions.some((tr2) => {
20437
- if (tr2.getMeta("updateListSync")) return true;
20438
- return tr2.steps.some((step) => {
20439
- const stepJSON = step.toJSON();
20440
- if (step.slice?.content) {
20441
- let hasListItem = false;
20442
- step.slice.content.descendants((node) => {
20443
- if (node.type.name === "listItem") {
20444
- hasListItem = true;
20445
- return false;
20446
- }
20447
- });
20448
- if (hasListItem) return true;
20449
- }
20450
- if (stepJSON && stepJSON.slice) {
20451
- const jsonStr = JSON.stringify(stepJSON);
20452
- if (jsonStr.includes('"listItem"')) return true;
20453
- }
20454
- return false;
20455
- });
20456
- });
20457
- if (!shouldProcess) return null;
19680
+ numberingManager.enableCache();
20458
19681
  newState.doc.descendants((node, pos) => {
20459
- if (node.type.name !== "listItem") return;
20460
- const { level: attrLvl, numId: attrNumId, styleId } = node.attrs;
20461
- const level = parseInt(attrLvl);
20462
- const numId = parseInt(attrNumId);
20463
- let {
20464
- lvlText,
20465
- customFormat,
20466
- listNumberingType,
20467
- start: numberingDefStart
20468
- } = ListHelpers.getListDefinitionDetails({ numId, level, editor });
20469
- const start2 = parseInt(numberingDefStart) || 1;
20470
- if (!listMap.has(numId)) {
20471
- const generatedLevels = {};
20472
- const initialPath = docxNumberingHelpers.generateListPath(level, numId, styleId, generatedLevels, docx);
20473
- listMap.set(numId, initialPath || []);
20474
- listInitialized.set(numId, false);
20475
- }
20476
- let currentListLevels = [...listMap.get(numId)];
20477
- if (!listInitialized.get(numId)) {
20478
- listInitialized.set(numId, true);
20479
- if (typeof start2 === "number") {
20480
- while (currentListLevels.length <= level) {
20481
- currentListLevels.push(0);
20482
- }
20483
- currentListLevels[level] = start2;
20484
- for (let i = level + 1; i < currentListLevels.length; i++) {
20485
- currentListLevels[i] = 0;
20486
- }
20487
- }
20488
- } else {
20489
- while (currentListLevels.length <= level) {
20490
- currentListLevels.push(0);
20491
- }
20492
- currentListLevels[level] = (currentListLevels[level] || 0) + 1;
20493
- for (let i = level + 1; i < currentListLevels.length; i++) {
20494
- currentListLevels[i] = 0;
20495
- }
19682
+ if (node.type.name !== "paragraph" || !node.attrs.numberingProperties) {
19683
+ return;
20496
19684
  }
20497
- if (currentListLevels.length === 0) {
20498
- currentListLevels = [1];
19685
+ const { numId, ilvl: level = 0 } = node.attrs.numberingProperties;
19686
+ const definitionDetails = ListHelpers.getListDefinitionDetails({ numId, level, editor });
19687
+ if (!definitionDetails || Object.keys(definitionDetails).length === 0) {
19688
+ tr.setNodeAttribute(pos, "listRendering", null);
19689
+ return;
20499
19690
  }
20500
- listMap.set(numId, currentListLevels);
20501
- const updatedAttrs = {
20502
- ...node.attrs,
20503
- listLevel: [...currentListLevels],
20504
- level,
20505
- lvlText,
20506
- listNumberingType,
20507
- customFormat
20508
- };
20509
- const keysChanged = Object.keys(updatedAttrs).some((key2) => node.attrs[key2] !== updatedAttrs[key2]);
20510
- if (keysChanged) {
20511
- tr.setNodeMarkup(pos, void 0, updatedAttrs);
19691
+ let { lvlText, customFormat, listNumberingType, suffix, justification, abstractId } = definitionDetails;
19692
+ let markerText = "";
19693
+ const count = numberingManager.calculateCounter(numId, level, pos, abstractId);
19694
+ numberingManager.setCounter(numId, level, pos, count, abstractId);
19695
+ const path = numberingManager.calculatePath(numId, level, pos);
19696
+ if (listNumberingType !== "bullet") {
19697
+ markerText = generateOrderedListIndex({
19698
+ listLevel: path,
19699
+ lvlText,
19700
+ listNumberingType,
19701
+ customFormat
19702
+ });
19703
+ } else {
19704
+ markerText = docxNumberingHelpers.normalizeLvlTextChar(lvlText);
19705
+ }
19706
+ if (JSON.stringify(node.attrs.listRendering) !== JSON.stringify({
19707
+ markerText,
19708
+ suffix,
19709
+ justification,
19710
+ path,
19711
+ numberingType: listNumberingType
19712
+ })) {
19713
+ tr.setNodeAttribute(pos, "listRendering", {
19714
+ markerText,
19715
+ suffix,
19716
+ justification,
19717
+ path,
19718
+ numberingType: listNumberingType
19719
+ });
20512
19720
  }
19721
+ return false;
20513
19722
  });
20514
- return tr;
19723
+ numberingManager.disableCache();
19724
+ return tr.docChanged ? tr : null;
20515
19725
  }
20516
19726
  });
20517
19727
  }
20518
- const ListItem = Node$1.create({
20519
- name: "listItem",
20520
- content: "paragraph* block*",
20521
- defining: true,
20522
- priority: 101,
20523
- // to run listItem commands first
20524
- addOptions() {
20525
- return {
20526
- htmlAttributes: {
20527
- "aria-label": "List item node"
20528
- },
20529
- bulletListTypeName: "bulletList",
20530
- orderedListTypeName: "orderedList"
20531
- };
20532
- },
20533
- parseDOM() {
20534
- return [{ tag: "li" }];
20535
- },
20536
- renderDOM({ htmlAttributes }) {
20537
- return ["li", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
20538
- },
20539
- addPmPlugins() {
20540
- return this.editor?.converter?.convertedXml ? [orderedListSync(this.editor)] : [];
20541
- },
20542
- /**
20543
- * Important: The listItem node uses a custom node view.
20544
- * Skip node view in headless mode for performance.
20545
- * @returns {import('@core/NodeView.js').NodeView|null}
20546
- */
20547
- addNodeView() {
20548
- if (shouldSkipNodeView(this.editor)) return null;
20549
- return ({ node, editor, getPos, decorations }) => {
20550
- return new ListItemNodeView(node, getPos, decorations, editor);
20551
- };
20552
- },
20553
- addAttributes() {
20554
- return {
20555
- // Virtual attribute.
20556
- markerType: {
20557
- default: null,
20558
- renderDOM: (attrs) => {
20559
- let { listLevel, listNumberingType, lvlText } = attrs;
20560
- let hasListLevel = !!listLevel?.length;
20561
- if (!hasListLevel || !lvlText) {
20562
- return {};
20563
- }
20564
- let orderMarker = generateOrderedListIndex({
20565
- listLevel,
20566
- lvlText,
20567
- listNumberingType
20568
- });
20569
- if (!orderMarker) return {};
20570
- return {
20571
- "data-marker-type": orderMarker
20572
- };
20573
- }
20574
- },
20575
- lvlText: {
20576
- default: null,
20577
- keepOnSplit: true,
20578
- parseDOM: (elem) => elem.getAttribute("data-lvl-text"),
20579
- renderDOM: (attrs) => {
20580
- if (!attrs.lvlText) return {};
20581
- return {
20582
- "data-lvl-text": attrs.lvlText
20583
- };
20584
- }
20585
- },
20586
- listNumberingType: {
20587
- default: null,
20588
- keepOnSplit: true,
20589
- parseDOM: (elem) => elem.getAttribute("data-num-fmt"),
20590
- renderDOM: (attrs) => {
20591
- if (!attrs.listNumberingType) return {};
20592
- return {
20593
- "data-num-fmt": attrs.listNumberingType
20594
- };
20595
- }
20596
- },
20597
- listLevel: {
20598
- default: null,
20599
- parseDOM: (elem) => {
20600
- let listLevel = elem.getAttribute("data-list-level");
20601
- try {
20602
- listLevel = JSON.parse(listLevel);
20603
- } catch {
20604
- }
20605
- return listLevel;
20606
- },
20607
- renderDOM: (attrs) => {
20608
- if (!attrs.listLevel) return {};
20609
- return {
20610
- "data-list-level": JSON.stringify(attrs.listLevel)
20611
- };
20612
- }
20613
- },
20614
- // JC = justification. Expect left, right, center
20615
- lvlJc: {
20616
- keepOnSplit: true,
20617
- default: null,
20618
- rendered: false
20619
- },
20620
- // This will contain indentation and space info.
20621
- // ie: w:left (left indent), w:hanging (hanging indent)
20622
- listParagraphProperties: {
20623
- keepOnSplit: true,
20624
- default: null,
20625
- rendered: false
20626
- },
20627
- // This will contain run properties for the list item
20628
- listRunProperties: {
20629
- keepOnSplit: true,
20630
- default: null,
20631
- rendered: false
20632
- },
20633
- numId: {
20634
- keepOnSplit: true,
20635
- default: null,
20636
- parseDOM: (elem) => elem.getAttribute("data-num-id"),
20637
- renderDOM: (attrs) => {
20638
- if (!attrs.numId) return {};
20639
- return {
20640
- "data-num-id": attrs.numId
20641
- };
20642
- }
20643
- },
20644
- numPrType: {
20645
- rendered: false,
20646
- default: "inline",
20647
- keepOnSplit: true
20648
- },
20649
- level: {
20650
- parseDOM: (elem) => {
20651
- return elem.getAttribute("data-level");
20652
- },
20653
- renderDOM: (attrs) => {
20654
- if (attrs.level === void 0 || attrs.level === null) return {};
20655
- return {
20656
- "data-level": attrs.level
20657
- };
20658
- }
20659
- },
20660
- attributes: {
20661
- keepOnSplit: true,
20662
- rendered: false
20663
- },
20664
- spacing: {
20665
- keepOnSplit: true,
20666
- default: null,
20667
- rendered: false
20668
- },
20669
- indent: {
20670
- parseDOM: (elem) => JSON.parse(elem.getAttribute("data-indent")),
20671
- keepOnSplit: true,
20672
- default: null,
20673
- rendered: false
20674
- },
20675
- markerStyle: {
20676
- default: null,
20677
- rendered: false,
20678
- keepOnSplit: true
20679
- },
20680
- styleId: {
20681
- rendered: false,
20682
- keepOnSplit: true
20683
- },
20684
- customFormat: {
20685
- default: null,
20686
- rendered: false,
20687
- keepOnSplit: true
20688
- },
20689
- importedFontFamily: {
20690
- parseDOM: (elem) => elem.getAttribute("data-font-family"),
20691
- renderDOM: (attrs) => {
20692
- if (!attrs.importedFontFamily) return {};
20693
- return {
20694
- "data-font-family": attrs.importedFontFamily
20695
- };
20696
- }
20697
- },
20698
- importedFontSize: {
20699
- parseDOM: (elem) => elem.getAttribute("data-font-size"),
20700
- renderDOM: (attrs) => {
20701
- if (!attrs.importedFontSize) return {};
20702
- return {
20703
- "data-font-size": attrs.importedFontSize
20704
- };
20705
- }
20706
- }
20707
- };
20708
- },
20709
- addShortcuts() {
20710
- return {
20711
- Enter: () => {
20712
- return this.editor.commands.splitListItem();
20713
- },
20714
- "Shift-Enter": () => {
20715
- return this.editor.commands.first(({ commands: commands2 }) => [
20716
- () => commands2.createParagraphNear(),
20717
- () => commands2.splitBlock()
20718
- ]);
20719
- },
20720
- Tab: () => {
20721
- return this.editor.commands.first(({ commands: commands2 }) => [() => commands2.increaseListIndent()]);
20722
- },
20723
- "Shift-Tab": () => {
20724
- return this.editor.commands.first(({ commands: commands2 }) => [() => commands2.decreaseListIndent()]);
20725
- }
20726
- };
20727
- }
20728
- });
20729
- const getDefaultSpacing = () => ({
20730
- after: null,
20731
- before: null,
20732
- line: null,
20733
- lineRule: "auto"
20734
- });
19728
+ const bulletInputRegex = /^\s*([-+*])\s$/;
19729
+ const orderedInputRegex = /^(\d+)\.\s$/;
20735
19730
  const Paragraph = OxmlNode.create({
20736
19731
  name: "paragraph",
20737
19732
  oXmlName: "w:p",
@@ -20769,12 +19764,16 @@ const Paragraph = OxmlNode.create({
20769
19764
  },
20770
19765
  renderDOM: (attrs) => {
20771
19766
  const { spacing, marksAttrs } = attrs;
20772
- if (!spacing) return {};
19767
+ if (!spacing) return { style: null };
20773
19768
  const spacingCopy = { ...spacing };
20774
19769
  if (attrs.lineHeight) delete spacingCopy.line;
20775
- const style = getSpacingStyleString(spacingCopy, marksAttrs ?? []);
19770
+ const style = getSpacingStyleString(
19771
+ spacingCopy,
19772
+ marksAttrs ?? [],
19773
+ Boolean(attrs.paragraphProperties?.numberingProperties)
19774
+ );
20776
19775
  if (style) return { style };
20777
- return {};
19776
+ return { style: null };
20778
19777
  }
20779
19778
  },
20780
19779
  extraAttrs: {
@@ -20802,10 +19801,10 @@ const Paragraph = OxmlNode.create({
20802
19801
  indent: {
20803
19802
  default: null,
20804
19803
  renderDOM: ({ indent }) => {
20805
- if (!indent) return {};
19804
+ if (!indent) return { style: null };
20806
19805
  const { left: left2, right: right2, firstLine, hanging } = indent;
20807
19806
  if (indent && Object.values(indent).every((v) => v === 0)) {
20808
- return {};
19807
+ return { style: null };
20809
19808
  }
20810
19809
  let style = "";
20811
19810
  if (left2) style += `margin-left: ${twipsToPixels(left2)}px;`;
@@ -20854,7 +19853,12 @@ const Paragraph = OxmlNode.create({
20854
19853
  return null;
20855
19854
  }
20856
19855
  },
20857
- styleId: {},
19856
+ styleId: {
19857
+ renderDOM: (attrs) => {
19858
+ if (!attrs.styleId) return {};
19859
+ return { styleid: attrs.styleId };
19860
+ }
19861
+ },
20858
19862
  sdBlockId: {
20859
19863
  default: null,
20860
19864
  keepOnSplit: false,
@@ -20883,7 +19887,26 @@ const Paragraph = OxmlNode.create({
20883
19887
  return { style };
20884
19888
  }
20885
19889
  },
20886
- tabStops: { rendered: false }
19890
+ tabStops: { rendered: false },
19891
+ listRendering: {
19892
+ keepOnSplit: false,
19893
+ renderDOM: ({ listRendering }) => {
19894
+ return {
19895
+ "data-marker-type": listRendering?.markerText,
19896
+ "data-list-level": listRendering?.path ? JSON.stringify(listRendering.path) : null,
19897
+ "data-list-numbering-type": listRendering?.numberingType
19898
+ };
19899
+ }
19900
+ },
19901
+ numberingProperties: {
19902
+ keepOnSplit: true,
19903
+ renderDOM: ({ numberingProperties }) => {
19904
+ return {
19905
+ "data-num-id": numberingProperties?.numId,
19906
+ "data-level": numberingProperties?.ilvl
19907
+ };
19908
+ }
19909
+ }
20887
19910
  };
20888
19911
  },
20889
19912
  parseDOM() {
@@ -20891,12 +19914,59 @@ const Paragraph = OxmlNode.create({
20891
19914
  {
20892
19915
  tag: "p",
20893
19916
  getAttrs: (node) => {
20894
- const { styleid, ...extraAttrs } = Array.from(node.attributes).reduce((acc, attr) => {
20895
- acc[attr.name] = attr.value;
19917
+ const numberingProperties = {};
19918
+ let indent, spacing;
19919
+ const { styleid: styleId, ...extraAttrs } = Array.from(node.attributes).reduce((acc, attr) => {
19920
+ if (attr.name === "data-num-id") {
19921
+ numberingProperties.numId = parseInt(attr.value);
19922
+ } else if (attr.name === "data-level") {
19923
+ numberingProperties.ilvl = parseInt(attr.value);
19924
+ } else if (attr.name === "data-indent") {
19925
+ try {
19926
+ indent = JSON.parse(attr.value);
19927
+ Object.keys(indent).forEach((key2) => {
19928
+ indent[key2] = Number(indent[key2]);
19929
+ });
19930
+ } catch {
19931
+ }
19932
+ } else if (attr.name === "data-spacing") {
19933
+ try {
19934
+ spacing = JSON.parse(attr.value);
19935
+ Object.keys(spacing).forEach((key2) => {
19936
+ spacing[key2] = Number(spacing[key2]);
19937
+ });
19938
+ } catch {
19939
+ }
19940
+ } else {
19941
+ acc[attr.name] = attr.value;
19942
+ }
20896
19943
  return acc;
20897
19944
  }, {});
19945
+ if (Object.keys(numberingProperties).length > 0) {
19946
+ const resolvedParagraphProperties = resolveParagraphProperties(
19947
+ { docx: this.editor.converter.convertedXml, numbering: this.editor.converter.numbering },
19948
+ { styleId, numberingProperties, indent, spacing },
19949
+ false,
19950
+ true
19951
+ );
19952
+ return {
19953
+ paragraphProperties: {
19954
+ numberingProperties,
19955
+ indent,
19956
+ spacing,
19957
+ styleId: styleId || null
19958
+ },
19959
+ indent: resolvedParagraphProperties.indent,
19960
+ spacing: resolvedParagraphProperties.spacing,
19961
+ numberingProperties,
19962
+ styleId: styleId || null,
19963
+ extraAttrs
19964
+ };
19965
+ }
20898
19966
  return {
20899
- styleId: styleid || null,
19967
+ styleId: styleId || null,
19968
+ indent,
19969
+ spacing,
20900
19970
  extraAttrs
20901
19971
  };
20902
19972
  }
@@ -20924,6 +19994,101 @@ const Paragraph = OxmlNode.create({
20924
19994
  renderDOM({ htmlAttributes }) {
20925
19995
  return ["p", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0];
20926
19996
  },
19997
+ addNodeView() {
19998
+ if (shouldSkipNodeView(this.editor)) return null;
19999
+ return ({ node, editor, getPos, decorations, extensionAttrs }) => {
20000
+ return new ParagraphNodeView(node, editor, getPos, decorations, extensionAttrs);
20001
+ };
20002
+ },
20003
+ addShortcuts() {
20004
+ return {
20005
+ "Mod-Shift-7": () => {
20006
+ return this.editor.commands.toggleOrderedList();
20007
+ },
20008
+ "Mod-Shift-8": () => {
20009
+ return this.editor.commands.toggleBulletList();
20010
+ },
20011
+ Enter: (params2) => {
20012
+ return removeNumberingProperties({ checkType: "empty" })({
20013
+ ...params2,
20014
+ tr: this.editor.state.tr,
20015
+ state: this.editor.state,
20016
+ dispatch: this.editor.view.dispatch
20017
+ });
20018
+ },
20019
+ "Shift-Enter": () => {
20020
+ return this.editor.commands.first(({ commands: commands2 }) => [
20021
+ () => commands2.createParagraphNear(),
20022
+ splitBlock$1({
20023
+ attrsToRemoveOverride: ["paragraphProperties.numberingProperties", "listRendering", "numberingProperties"]
20024
+ })
20025
+ ]);
20026
+ },
20027
+ Tab: () => {
20028
+ return this.editor.commands.first(({ commands: commands2 }) => [() => commands2.increaseListIndent()]);
20029
+ },
20030
+ "Shift-Tab": () => {
20031
+ return this.editor.commands.first(({ commands: commands2 }) => [() => commands2.decreaseListIndent()]);
20032
+ }
20033
+ };
20034
+ },
20035
+ addInputRules() {
20036
+ return [
20037
+ { regex: orderedInputRegex, type: "orderedList" },
20038
+ { regex: bulletInputRegex, type: "bulletList" }
20039
+ ].map(
20040
+ ({ regex, type }) => new InputRule({
20041
+ match: regex,
20042
+ handler: ({ state, range }) => {
20043
+ const parentListItem = findParentNode(isList)(state.selection);
20044
+ if (parentListItem) {
20045
+ return null;
20046
+ }
20047
+ const { tr } = state;
20048
+ tr.delete(range.from, range.to);
20049
+ ListHelpers.createNewList({
20050
+ listType: type,
20051
+ tr,
20052
+ editor: this.editor
20053
+ });
20054
+ }
20055
+ })
20056
+ );
20057
+ },
20058
+ addCommands() {
20059
+ return {
20060
+ /**
20061
+ * Toggle ordered list formatting
20062
+ * @category Command
20063
+ * @example
20064
+ * editor.commands.toggleOrderedList()
20065
+ * @note Converts selection to ordered list or back to paragraphs
20066
+ */
20067
+ toggleOrderedList: () => (params2) => {
20068
+ return toggleList("orderedList")(params2);
20069
+ },
20070
+ /**
20071
+ * Toggle a bullet list at the current selection
20072
+ * @category Command
20073
+ * @example
20074
+ * // Toggle bullet list on selected text
20075
+ * editor.commands.toggleBulletList()
20076
+ * @note Converts selected paragraphs to list items or removes list formatting
20077
+ */
20078
+ toggleBulletList: () => (params2) => {
20079
+ return toggleList("bulletList")(params2);
20080
+ },
20081
+ /**
20082
+ * Restart numbering for the current list
20083
+ * @category Command
20084
+ * @example
20085
+ * // Restart numbering for the current list item
20086
+ * editor.commands.restartNumbering()
20087
+ * @note Resets list numbering for the current list item and following items
20088
+ */
20089
+ restartNumbering: () => restartNumbering
20090
+ };
20091
+ },
20927
20092
  addPmPlugins() {
20928
20093
  const { view } = this.editor;
20929
20094
  const dropcapWidthCache = /* @__PURE__ */ new Map();
@@ -20997,7 +20162,8 @@ const Paragraph = OxmlNode.create({
20997
20162
  }
20998
20163
  }
20999
20164
  });
21000
- return [dropcapPlugin];
20165
+ const numberingPlugin = createNumberingPlugin(this.editor);
20166
+ return [dropcapPlugin, numberingPlugin];
21001
20167
  }
21002
20168
  });
21003
20169
  const getDropcapDecorations = (state, view, widthCache) => {
@@ -21194,265 +20360,6 @@ const CommentsMark = Mark.create({
21194
20360
  return [CommentMarkName, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
21195
20361
  }
21196
20362
  });
21197
- const defaultTabDistance = 48;
21198
- const defaultLineLength = 816;
21199
- const getTabDecorations = (doc2, view, helpers2, from2 = 0, to = null) => {
21200
- const decorations = [];
21201
- const paragraphCache = /* @__PURE__ */ new Map();
21202
- const coordCache = /* @__PURE__ */ new Map();
21203
- const domPosCache = /* @__PURE__ */ new Map();
21204
- const end2 = to ?? doc2.content.size;
21205
- doc2.nodesBetween(from2, end2, (node, pos) => {
21206
- if (node.type.name !== "tab") return;
21207
- let extraStyles = "";
21208
- const $pos = doc2.resolve(pos);
21209
- const paragraphContext = getParagraphContext($pos, paragraphCache, helpers2);
21210
- if (!paragraphContext) return;
21211
- try {
21212
- const { tabStops, flattened, positionMap, startPos } = paragraphContext;
21213
- const entryIndex = positionMap.get(pos);
21214
- if (entryIndex === void 0) return;
21215
- if (paragraphContext.indentWidth === void 0) {
21216
- paragraphContext.indentWidth = getIndentWidth(view, startPos, paragraphContext.indent, coordCache, domPosCache);
21217
- }
21218
- if (paragraphContext.tabHeight === void 0) {
21219
- paragraphContext.tabHeight = calcTabHeight($pos);
21220
- }
21221
- const indentWidth = paragraphContext.indentWidth;
21222
- const accumulatedTabWidth = paragraphContext.accumulatedTabWidth || 0;
21223
- const currentWidth = indentWidth + measureRangeWidth(view, startPos + 1, pos, coordCache, domPosCache) + accumulatedTabWidth;
21224
- let tabWidth;
21225
- if (tabStops.length) {
21226
- const tabStop = tabStops.find((stop) => stop.pos > currentWidth && stop.val !== "clear");
21227
- if (tabStop) {
21228
- tabWidth = tabStop.pos - currentWidth;
21229
- let val = tabStop.val;
21230
- const aliases = { left: "start", right: "end" };
21231
- if (aliases[val]) val = aliases[val];
21232
- if (val === "center" || val === "end" || val === "right") {
21233
- const nextTabIndex = findNextTabIndex(flattened, entryIndex + 1);
21234
- const segmentStartPos = pos + node.nodeSize;
21235
- const segmentEndPos = nextTabIndex === -1 ? startPos + paragraphContext.paragraph.nodeSize - 1 : flattened[nextTabIndex].pos;
21236
- const segmentWidth = measureRangeWidth(view, segmentStartPos, segmentEndPos, coordCache, domPosCache);
21237
- tabWidth -= val === "center" ? segmentWidth / 2 : segmentWidth;
21238
- } else if (val === "decimal" || val === "num") {
21239
- const breakChar = tabStop.decimalChar || ".";
21240
- const decimalPos = findDecimalBreakPos(flattened, entryIndex + 1, breakChar);
21241
- const integralWidth = decimalPos ? measureRangeWidth(view, pos + node.nodeSize, decimalPos, coordCache, domPosCache) : measureRangeWidth(
21242
- view,
21243
- pos + node.nodeSize,
21244
- startPos + paragraphContext.paragraph.nodeSize - 1,
21245
- coordCache,
21246
- domPosCache
21247
- );
21248
- tabWidth -= integralWidth;
21249
- }
21250
- if (tabStop.leader) {
21251
- const leaderStyles = {
21252
- dot: "border-bottom: 1px dotted black;",
21253
- heavy: "border-bottom: 2px solid black;",
21254
- hyphen: "border-bottom: 1px solid black;",
21255
- middleDot: "border-bottom: 1px dotted black; margin-bottom: 2px;",
21256
- underscore: "border-bottom: 1px solid black;"
21257
- };
21258
- extraStyles += leaderStyles[tabStop.leader] || "";
21259
- }
21260
- }
21261
- }
21262
- if (!tabWidth || tabWidth < 1) {
21263
- tabWidth = defaultTabDistance - currentWidth % defaultLineLength % defaultTabDistance;
21264
- if (tabWidth === 0) tabWidth = defaultTabDistance;
21265
- }
21266
- const tabHeight = paragraphContext.tabHeight;
21267
- decorations.push(
21268
- Decoration.node(pos, pos + node.nodeSize, {
21269
- style: `width: ${tabWidth}px; height: ${tabHeight};${extraStyles}`
21270
- })
21271
- );
21272
- paragraphContext.accumulatedTabWidth = accumulatedTabWidth + tabWidth;
21273
- } catch (error) {
21274
- console.error("tab decoration error", error);
21275
- }
21276
- });
21277
- return decorations;
21278
- };
21279
- function getParagraphContext($pos, cache, helpers2) {
21280
- for (let depth = $pos.depth; depth >= 0; depth--) {
21281
- const node = $pos.node(depth);
21282
- if (node?.type?.name === "paragraph") {
21283
- const startPos = $pos.start(depth);
21284
- if (!cache.has(startPos)) {
21285
- let tabStops = [];
21286
- if (Array.isArray(node.attrs?.tabStops)) {
21287
- tabStops = node.attrs.tabStops.map((stop) => {
21288
- const ref2 = stop?.tab;
21289
- if (!ref2) return stop || null;
21290
- return {
21291
- val: ref2.tabType || "start",
21292
- pos: twipsToPixels(Number(ref2.pos) || 0),
21293
- leader: ref2.leader
21294
- };
21295
- }).filter(Boolean);
21296
- } else {
21297
- const style = helpers2.linkedStyles.getStyleById(node.attrs?.styleId);
21298
- if (Array.isArray(style?.definition?.styles?.tabStops)) {
21299
- tabStops = style.definition.styles.tabStops;
21300
- }
21301
- }
21302
- const { entries, positionMap } = flattenParagraph(node, startPos);
21303
- cache.set(startPos, {
21304
- paragraph: node,
21305
- paragraphDepth: depth,
21306
- startPos,
21307
- indent: node.attrs?.indent || {},
21308
- tabStops,
21309
- flattened: entries,
21310
- positionMap,
21311
- // Store position map for O(1) lookups
21312
- accumulatedTabWidth: 0
21313
- });
21314
- }
21315
- return cache.get(startPos);
21316
- }
21317
- }
21318
- return null;
21319
- }
21320
- function flattenParagraph(paragraph, paragraphStartPos) {
21321
- const entries = [];
21322
- const positionMap = /* @__PURE__ */ new Map();
21323
- const walk = (node, basePos) => {
21324
- if (!node) return;
21325
- if (node.type?.name === "run") {
21326
- node.forEach((child, offset2) => {
21327
- const childPos = basePos + offset2 + 1;
21328
- walk(child, childPos);
21329
- });
21330
- return;
21331
- }
21332
- const pos = basePos - 1;
21333
- const index2 = entries.length;
21334
- entries.push({ node, pos });
21335
- positionMap.set(pos, index2);
21336
- };
21337
- paragraph.forEach((child, offset2) => {
21338
- const childPos = paragraphStartPos + offset2 + 1;
21339
- walk(child, childPos);
21340
- });
21341
- return { entries, positionMap };
21342
- }
21343
- function findNextTabIndex(flattened, fromIndex) {
21344
- for (let i = fromIndex; i < flattened.length; i++) {
21345
- if (flattened[i]?.node?.type?.name === "tab") {
21346
- return i;
21347
- }
21348
- }
21349
- return -1;
21350
- }
21351
- function findDecimalBreakPos(flattened, startIndex, breakChar) {
21352
- for (let i = startIndex; i < flattened.length; i++) {
21353
- const entry = flattened[i];
21354
- if (!entry) break;
21355
- if (entry.node.type?.name === "tab") break;
21356
- if (entry.node.type?.name === "text") {
21357
- const index2 = entry.node.text?.indexOf(breakChar);
21358
- if (index2 !== void 0 && index2 !== -1) {
21359
- return entry.pos + index2 + 1;
21360
- }
21361
- }
21362
- }
21363
- return null;
21364
- }
21365
- function measureRangeWidth(view, from2, to, coordCache = null, domPosCache = null) {
21366
- if (!Number.isFinite(from2) || !Number.isFinite(to) || to <= from2) return 0;
21367
- try {
21368
- const range = document.createRange();
21369
- const fromRef = getCachedDomAtPos(view, from2, domPosCache);
21370
- const toRef = getCachedDomAtPos(view, to, domPosCache);
21371
- range.setStart(fromRef.node, fromRef.offset);
21372
- range.setEnd(toRef.node, toRef.offset);
21373
- const rect = range.getBoundingClientRect();
21374
- range.detach?.();
21375
- return rect.width || 0;
21376
- } catch {
21377
- const startLeft = getLeftCoord(view, from2, coordCache, domPosCache);
21378
- const endLeft = getLeftCoord(view, to, coordCache, domPosCache);
21379
- if (startLeft == null || endLeft == null) return 0;
21380
- return Math.max(0, endLeft - startLeft);
21381
- }
21382
- }
21383
- function getIndentWidth(view, paragraphStartPos, indentAttrs = {}, coordCache = null, domPosCache = null) {
21384
- const marginLeft = getLeftCoord(view, paragraphStartPos, coordCache, domPosCache);
21385
- const lineLeft = getLeftCoord(view, paragraphStartPos + 1, coordCache, domPosCache);
21386
- if (marginLeft != null && lineLeft != null) {
21387
- const diff = lineLeft - marginLeft;
21388
- if (!Number.isNaN(diff) && Math.abs(diff) > 0.5) {
21389
- return diff;
21390
- }
21391
- }
21392
- return calculateIndentFallback(indentAttrs);
21393
- }
21394
- function calculateIndentFallback(indentAttrs = {}) {
21395
- if (!indentAttrs) return 0;
21396
- const left2 = twipsToPixels(Number(indentAttrs.left) || 0);
21397
- const firstLine = twipsToPixels(Number(indentAttrs.firstLine) || 0);
21398
- const hanging = twipsToPixels(Number(indentAttrs.hanging) || 0);
21399
- let textIndent = 0;
21400
- if (firstLine && hanging) {
21401
- textIndent = firstLine - hanging;
21402
- } else if (firstLine) {
21403
- textIndent = firstLine;
21404
- } else if (hanging) {
21405
- textIndent = -hanging;
21406
- }
21407
- if (textIndent) return left2 + textIndent;
21408
- if (left2) return left2;
21409
- return 0;
21410
- }
21411
- function getLeftCoord(view, pos, coordCache = null, domPosCache = null) {
21412
- if (!Number.isFinite(pos)) return null;
21413
- if (coordCache && coordCache.has(pos)) {
21414
- return coordCache.get(pos);
21415
- }
21416
- let result = null;
21417
- try {
21418
- result = view.coordsAtPos(pos).left;
21419
- } catch {
21420
- try {
21421
- const ref2 = getCachedDomAtPos(view, pos, domPosCache);
21422
- const range = document.createRange();
21423
- range.setStart(ref2.node, ref2.offset);
21424
- range.setEnd(ref2.node, ref2.offset);
21425
- const rect = range.getBoundingClientRect();
21426
- range.detach?.();
21427
- result = rect.left;
21428
- } catch {
21429
- result = null;
21430
- }
21431
- }
21432
- if (coordCache) {
21433
- coordCache.set(pos, result);
21434
- }
21435
- return result;
21436
- }
21437
- function getCachedDomAtPos(view, pos, domPosCache = null) {
21438
- if (domPosCache && domPosCache.has(pos)) {
21439
- return domPosCache.get(pos);
21440
- }
21441
- const result = view.domAtPos(pos);
21442
- if (domPosCache) {
21443
- domPosCache.set(pos, result);
21444
- }
21445
- return result;
21446
- }
21447
- function calcTabHeight(pos) {
21448
- const ptToPxRatio = 1.333;
21449
- const defaultFontSize = 16;
21450
- const defaultLineHeight = 1.1;
21451
- const blockParent2 = pos.node(1);
21452
- const parentTextStyleMark = blockParent2.firstChild.marks.find((mark) => mark.type.name === "textStyle");
21453
- const fontSize = parseInt(parentTextStyleMark?.attrs.fontSize) * ptToPxRatio || defaultFontSize;
21454
- return `${fontSize * defaultLineHeight}px`;
21455
- }
21456
20363
  const TabNode = Node$1.create({
21457
20364
  name: "tab",
21458
20365
  group: "inline",
@@ -25804,42 +24711,60 @@ function toHex(color) {
25804
24711
  };
25805
24712
  return `#${hex(r2)}${hex(g)}${hex(b)}${a < 1 ? hex(Math.round(a * 255)) : ""}`;
25806
24713
  }
24714
+ const summarizeListContent = (node, fieldsToDeleteSet) => {
24715
+ const summary = {
24716
+ totalFieldAnnotations: 0,
24717
+ deletableFieldAnnotations: 0,
24718
+ hasOtherInlineContent: false
24719
+ };
24720
+ if (typeof node?.descendants !== "function") {
24721
+ return summary;
24722
+ }
24723
+ node.descendants((child) => {
24724
+ if (!child) return true;
24725
+ if (child.type?.name === "fieldAnnotation") {
24726
+ summary.totalFieldAnnotations += 1;
24727
+ const fieldId = child.attrs?.fieldId;
24728
+ if (fieldId && fieldsToDeleteSet.has(fieldId)) {
24729
+ summary.deletableFieldAnnotations += 1;
24730
+ } else {
24731
+ summary.hasOtherInlineContent = true;
24732
+ }
24733
+ return false;
24734
+ }
24735
+ if (child.isText) {
24736
+ if (child.text?.trim()) {
24737
+ summary.hasOtherInlineContent = true;
24738
+ }
24739
+ return false;
24740
+ }
24741
+ if (child.isInline || child.isAtom) {
24742
+ summary.hasOtherInlineContent = true;
24743
+ return false;
24744
+ }
24745
+ return true;
24746
+ });
24747
+ return summary;
24748
+ };
25807
24749
  const cleanUpListsWithAnnotations = (fieldsToDelete = []) => ({ dispatch, tr, state }) => {
25808
24750
  if (!dispatch) return true;
25809
24751
  if (!Array.isArray(fieldsToDelete)) fieldsToDelete = [fieldsToDelete];
24752
+ const fieldsToDeleteSet = new Set(fieldsToDelete);
25810
24753
  const { doc: doc2 } = state;
25811
24754
  const docxAnnotations = getAllFieldAnnotations(state) || [];
25812
24755
  const nodesToDelete = [];
25813
24756
  fieldsToDelete.forEach((fieldId) => {
25814
24757
  const matched = docxAnnotations.find((a) => a.node.attrs.fieldId === fieldId);
25815
24758
  if (!matched) return;
25816
- const listItem = findParentNodeClosestToPos(doc2.resolve(matched.pos), (node2) => node2.type.name === "listItem");
24759
+ const listItem = findParentNodeClosestToPos(doc2.resolve(matched.pos), isList);
25817
24760
  if (!listItem) return;
25818
- let remainingNodes = 0;
25819
- listItem.node.descendants((node2) => {
25820
- if (node2.type.name === "fieldAnnotation") {
25821
- remainingNodes += 1;
25822
- }
25823
- });
25824
- let matchingNodesFound = 0;
25825
- let hasOtherNodes = false;
25826
- listItem.node.children.forEach((child) => {
25827
- const { type } = child;
25828
- if (type.name !== "paragraph" && type.name !== "fieldAnnotation") return;
25829
- child.children.forEach((inline) => {
25830
- const isFieldToDelete = fieldsToDelete.includes(inline.attrs.fieldId);
25831
- const isFieldType = inline.type.name === "fieldAnnotation";
25832
- const isMatchingField = isFieldType && isFieldToDelete;
25833
- if (!isFieldType && !isMatchingField) hasOtherNodes = true;
25834
- if (isMatchingField) matchingNodesFound += 1;
25835
- });
25836
- });
25837
- if (!hasOtherNodes && matchingNodesFound > 0) {
25838
- remainingNodes -= matchingNodesFound;
25839
- }
25840
- if (remainingNodes > 0) {
25841
- return;
25842
- }
24761
+ const { totalFieldAnnotations, deletableFieldAnnotations, hasOtherInlineContent } = summarizeListContent(
24762
+ listItem.node,
24763
+ fieldsToDeleteSet
24764
+ );
24765
+ if (!totalFieldAnnotations) return;
24766
+ if (hasOtherInlineContent) return;
24767
+ if (totalFieldAnnotations !== deletableFieldAnnotations) return;
25843
24768
  let { pos, node, depth } = listItem;
25844
24769
  let $pos = doc2.resolve(pos);
25845
24770
  while (depth > 0) {
@@ -31769,6 +30694,21 @@ const TextStyle = Mark.create({
31769
30694
  if (!hasStyles || isAnnotation) return false;
31770
30695
  return {};
31771
30696
  }
30697
+ },
30698
+ {
30699
+ getAttrs: (node) => {
30700
+ const fontFamily = node.style.fontFamily?.replace(/['"]+/g, "");
30701
+ const fontSize = node.style.fontSize;
30702
+ const textTransform = node.style.textTransform;
30703
+ if (fontFamily || fontSize || textTransform) {
30704
+ return {
30705
+ fontFamily: fontFamily || null,
30706
+ fontSize: fontSize || null,
30707
+ textTransform: textTransform || null
30708
+ };
30709
+ }
30710
+ return false;
30711
+ }
31772
30712
  }
31773
30713
  ];
31774
30714
  },
@@ -38552,7 +37492,6 @@ const NodeResizer = Extension.create({
38552
37492
  const getRichTextExtensions = () => {
38553
37493
  return [
38554
37494
  Bold,
38555
- BulletList,
38556
37495
  Color,
38557
37496
  Document,
38558
37497
  FontFamily,
@@ -38560,10 +37499,8 @@ const getRichTextExtensions = () => {
38560
37499
  History,
38561
37500
  Heading,
38562
37501
  Italic,
38563
- ListItem,
38564
37502
  LineHeight,
38565
37503
  Link,
38566
- OrderedList,
38567
37504
  Paragraph,
38568
37505
  Strike,
38569
37506
  Text,
@@ -38595,7 +37532,6 @@ const getStarterExtensions = () => {
38595
37532
  return [
38596
37533
  Bold,
38597
37534
  BlockNode,
38598
- BulletList,
38599
37535
  Color,
38600
37536
  CommentRangeStart,
38601
37537
  CommentRangeEnd,
@@ -38606,10 +37542,8 @@ const getStarterExtensions = () => {
38606
37542
  History,
38607
37543
  Heading,
38608
37544
  Italic,
38609
- ListItem,
38610
37545
  LineHeight,
38611
37546
  Link,
38612
- OrderedList,
38613
37547
  Paragraph,
38614
37548
  LineBreak,
38615
37549
  HardBreak,
@@ -38682,28 +37616,27 @@ export {
38682
37616
  _export_sfc as _,
38683
37617
  getQuickFormatList as a,
38684
37618
  generateLinkedStyleString as b,
38685
- collectTargetListItemPositions as c,
38686
- getFileOpener as d,
38687
- checkAndProcessImage as e,
38688
- uploadAndInsertImage as f,
37619
+ getFileOpener as c,
37620
+ checkAndProcessImage as d,
37621
+ uploadAndInsertImage as e,
37622
+ collectTrackedChanges as f,
38689
37623
  global as g,
38690
- collectTrackedChanges as h,
37624
+ undoDepth as h,
38691
37625
  isTrackedChangeActionAllowed as i,
38692
- undoDepth as j,
38693
- redoDepth as k,
38694
- collectTrackedChangesForContext as l,
38695
- isHeadless as m,
38696
- getStarterExtensions as n,
38697
- getRichTextExtensions as o,
38698
- Decoration as p,
38699
- Extension as q,
37626
+ redoDepth as j,
37627
+ collectTrackedChangesForContext as k,
37628
+ isHeadless as l,
37629
+ getStarterExtensions as m,
37630
+ getRichTextExtensions as n,
37631
+ Decoration as o,
37632
+ Extension as p,
37633
+ index$1 as q,
38700
37634
  replaceSelectionWithImagePlaceholder as r,
38701
37635
  shouldBypassContextMenu as s,
38702
- index$1 as t,
37636
+ index as t,
38703
37637
  useHighContrastMode as u,
38704
- index as v,
38705
- AnnotatorHelpers as w,
38706
- SectionHelpers as x,
38707
- yUndoPluginKey as y,
38708
- getAllowedImageDimensions as z
37638
+ AnnotatorHelpers as v,
37639
+ SectionHelpers as w,
37640
+ getAllowedImageDimensions as x,
37641
+ yUndoPluginKey as y
38709
37642
  };