@portone/docx-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/CONTRIBUTING.md +63 -0
  3. package/LICENSE +203 -0
  4. package/README.md +48 -0
  5. package/assets/editor.png +0 -0
  6. package/dist/DocxEditor.d.ts +123 -0
  7. package/dist/DocxEditor.js +348 -0
  8. package/dist/core.d.ts +36 -0
  9. package/dist/core.js +38 -0
  10. package/dist/docx/comments/constants.d.ts +8 -0
  11. package/dist/docx/comments/constants.js +20 -0
  12. package/dist/docx/comments/model.d.ts +37 -0
  13. package/dist/docx/comments/model.js +104 -0
  14. package/dist/docx/comments/reading.d.ts +36 -0
  15. package/dist/docx/comments/reading.js +149 -0
  16. package/dist/docx/comments/writing.d.ts +11 -0
  17. package/dist/docx/comments/writing.js +327 -0
  18. package/dist/docx/comments.d.ts +3 -0
  19. package/dist/docx/comments.js +4 -0
  20. package/dist/docx/container.d.ts +12 -0
  21. package/dist/docx/container.js +130 -0
  22. package/dist/docx/documentSettings.d.ts +4 -0
  23. package/dist/docx/documentSettings.js +14 -0
  24. package/dist/docx/exportDocx.d.ts +15 -0
  25. package/dist/docx/exportDocx.js +163 -0
  26. package/dist/docx/exportRefs.d.ts +16 -0
  27. package/dist/docx/exportRefs.js +10 -0
  28. package/dist/docx/formatting/direct.d.ts +30 -0
  29. package/dist/docx/formatting/direct.js +201 -0
  30. package/dist/docx/formatting/effectiveParagraph.d.ts +15 -0
  31. package/dist/docx/formatting/effectiveParagraph.js +81 -0
  32. package/dist/docx/formatting/styles.d.ts +67 -0
  33. package/dist/docx/formatting/styles.js +165 -0
  34. package/dist/docx/formatting/tabStops.d.ts +8 -0
  35. package/dist/docx/formatting/tabStops.js +65 -0
  36. package/dist/docx/formatting.d.ts +4 -0
  37. package/dist/docx/formatting.js +4 -0
  38. package/dist/docx/headersFooters.d.ts +36 -0
  39. package/dist/docx/headersFooters.js +218 -0
  40. package/dist/docx/hyperlink.d.ts +75 -0
  41. package/dist/docx/hyperlink.js +71 -0
  42. package/dist/docx/importDocx.d.ts +21 -0
  43. package/dist/docx/importDocx.js +263 -0
  44. package/dist/docx/importParagraph.d.ts +32 -0
  45. package/dist/docx/importParagraph.js +308 -0
  46. package/dist/docx/importTable.d.ts +9 -0
  47. package/dist/docx/importTable.js +275 -0
  48. package/dist/docx/media.d.ts +60 -0
  49. package/dist/docx/media.js +213 -0
  50. package/dist/docx/notes.d.ts +22 -0
  51. package/dist/docx/notes.js +71 -0
  52. package/dist/docx/pageGeometry.d.ts +75 -0
  53. package/dist/docx/pageGeometry.js +88 -0
  54. package/dist/docx/paraProps.d.ts +74 -0
  55. package/dist/docx/paraProps.js +167 -0
  56. package/dist/docx/propsXml.d.ts +49 -0
  57. package/dist/docx/propsXml.js +302 -0
  58. package/dist/docx/relationships.d.ts +42 -0
  59. package/dist/docx/relationships.js +94 -0
  60. package/dist/docx/runProps.d.ts +51 -0
  61. package/dist/docx/runProps.js +207 -0
  62. package/dist/docx/scan.d.ts +20 -0
  63. package/dist/docx/scan.js +110 -0
  64. package/dist/docx/sdt.d.ts +56 -0
  65. package/dist/docx/sdt.js +104 -0
  66. package/dist/docx/sdtProps.d.ts +18 -0
  67. package/dist/docx/sdtProps.js +11 -0
  68. package/dist/docx/serializeBlock.d.ts +4 -0
  69. package/dist/docx/serializeBlock.js +30 -0
  70. package/dist/docx/serializeParagraph.d.ts +15 -0
  71. package/dist/docx/serializeParagraph.js +208 -0
  72. package/dist/docx/serializeTable.d.ts +12 -0
  73. package/dist/docx/serializeTable.js +134 -0
  74. package/dist/docx/session.d.ts +81 -0
  75. package/dist/docx/session.js +79 -0
  76. package/dist/docx/tableFormatting/editing.d.ts +64 -0
  77. package/dist/docx/tableFormatting/editing.js +318 -0
  78. package/dist/docx/tableFormatting/reading.d.ts +96 -0
  79. package/dist/docx/tableFormatting/reading.js +221 -0
  80. package/dist/docx/tableFormatting.d.ts +2 -0
  81. package/dist/docx/tableFormatting.js +3 -0
  82. package/dist/docx/tableTemplate.d.ts +22 -0
  83. package/dist/docx/tableTemplate.js +111 -0
  84. package/dist/docx/theme.d.ts +40 -0
  85. package/dist/docx/theme.js +61 -0
  86. package/dist/docx/uniqueControls.d.ts +14 -0
  87. package/dist/docx/uniqueControls.js +62 -0
  88. package/dist/download.d.ts +57 -0
  89. package/dist/download.js +44 -0
  90. package/dist/editor/clipboard/images.d.ts +14 -0
  91. package/dist/editor/clipboard/images.js +158 -0
  92. package/dist/editor/clipboard/inlineFormatting.d.ts +21 -0
  93. package/dist/editor/clipboard/inlineFormatting.js +232 -0
  94. package/dist/editor/commands/breakCommands.d.ts +8 -0
  95. package/dist/editor/commands/breakCommands.js +19 -0
  96. package/dist/editor/commands/canRunCommand.d.ts +6 -0
  97. package/dist/editor/commands/canRunCommand.js +10 -0
  98. package/dist/editor/commands/commentCommands.d.ts +3 -0
  99. package/dist/editor/commands/commentCommands.js +4 -0
  100. package/dist/editor/commands/comments/editing.d.ts +21 -0
  101. package/dist/editor/commands/comments/editing.js +305 -0
  102. package/dist/editor/commands/comments/model.d.ts +31 -0
  103. package/dist/editor/commands/comments/model.js +0 -0
  104. package/dist/editor/commands/comments/reading.d.ts +8 -0
  105. package/dist/editor/commands/comments/reading.js +58 -0
  106. package/dist/editor/commands/formatting/editing.d.ts +32 -0
  107. package/dist/editor/commands/formatting/editing.js +138 -0
  108. package/dist/editor/commands/formatting/reading.d.ts +57 -0
  109. package/dist/editor/commands/formatting/reading.js +82 -0
  110. package/dist/editor/commands/formatting/shared.d.ts +32 -0
  111. package/dist/editor/commands/formatting/shared.js +53 -0
  112. package/dist/editor/commands/formattingCommands.d.ts +2 -0
  113. package/dist/editor/commands/formattingCommands.js +3 -0
  114. package/dist/editor/commands/historyCommands.d.ts +11 -0
  115. package/dist/editor/commands/historyCommands.js +16 -0
  116. package/dist/editor/commands/indentCommands.d.ts +15 -0
  117. package/dist/editor/commands/indentCommands.js +44 -0
  118. package/dist/editor/commands/index.d.ts +82 -0
  119. package/dist/editor/commands/index.js +171 -0
  120. package/dist/editor/commands/linkCommands.d.ts +56 -0
  121. package/dist/editor/commands/linkCommands.js +146 -0
  122. package/dist/editor/commands/listCommands.d.ts +58 -0
  123. package/dist/editor/commands/listCommands.js +140 -0
  124. package/dist/editor/commands/lockCommands.d.ts +47 -0
  125. package/dist/editor/commands/lockCommands.js +198 -0
  126. package/dist/editor/commands/noteQueries.d.ts +12 -0
  127. package/dist/editor/commands/noteQueries.js +29 -0
  128. package/dist/editor/commands/paragraphCommands.d.ts +59 -0
  129. package/dist/editor/commands/paragraphCommands.js +113 -0
  130. package/dist/editor/commands/spacingCommands.d.ts +23 -0
  131. package/dist/editor/commands/spacingCommands.js +48 -0
  132. package/dist/editor/commands/tabCommands.d.ts +5 -0
  133. package/dist/editor/commands/tabCommands.js +65 -0
  134. package/dist/editor/createEditor.d.ts +59 -0
  135. package/dist/editor/createEditor.js +160 -0
  136. package/dist/editor/documentStyles.d.ts +60 -0
  137. package/dist/editor/documentStyles.js +80 -0
  138. package/dist/editor/externalClipboard.d.ts +11 -0
  139. package/dist/editor/externalClipboard.js +323 -0
  140. package/dist/editor/imageFiles.d.ts +74 -0
  141. package/dist/editor/imageFiles.js +173 -0
  142. package/dist/editor/insertImage.d.ts +31 -0
  143. package/dist/editor/insertImage.js +35 -0
  144. package/dist/editor/insertTable.d.ts +18 -0
  145. package/dist/editor/insertTable.js +44 -0
  146. package/dist/editor/paragraphEdits.d.ts +42 -0
  147. package/dist/editor/paragraphEdits.js +59 -0
  148. package/dist/editor/plainText.d.ts +3 -0
  149. package/dist/editor/plainText.js +50 -0
  150. package/dist/editor/plugins/bookmarkProtection.d.ts +3 -0
  151. package/dist/editor/plugins/bookmarkProtection.js +28 -0
  152. package/dist/editor/plugins/columnResize.d.ts +27 -0
  153. package/dist/editor/plugins/columnResize.js +192 -0
  154. package/dist/editor/plugins/commentDecorations.d.ts +3 -0
  155. package/dist/editor/plugins/commentDecorations.js +23 -0
  156. package/dist/editor/plugins/commentReservations.d.ts +5 -0
  157. package/dist/editor/plugins/commentReservations.js +26 -0
  158. package/dist/editor/plugins/dropCaret.d.ts +10 -0
  159. package/dist/editor/plugins/dropCaret.js +11 -0
  160. package/dist/editor/plugins/imagePaste.d.ts +8 -0
  161. package/dist/editor/plugins/imagePaste.js +265 -0
  162. package/dist/editor/plugins/keymap.d.ts +5 -0
  163. package/dist/editor/plugins/keymap.js +94 -0
  164. package/dist/editor/plugins/linkPanel.d.ts +23 -0
  165. package/dist/editor/plugins/linkPanel.js +39 -0
  166. package/dist/editor/plugins/listInputRules.d.ts +14 -0
  167. package/dist/editor/plugins/listInputRules.js +36 -0
  168. package/dist/editor/plugins/lockedContent.d.ts +6 -0
  169. package/dist/editor/plugins/lockedContent.js +41 -0
  170. package/dist/editor/plugins/noteProtection.d.ts +3 -0
  171. package/dist/editor/plugins/noteProtection.js +25 -0
  172. package/dist/editor/plugins/numberingDecorations.d.ts +42 -0
  173. package/dist/editor/plugins/numberingDecorations.js +110 -0
  174. package/dist/editor/plugins/rowResize.d.ts +15 -0
  175. package/dist/editor/plugins/rowResize.js +196 -0
  176. package/dist/editor/plugins/styledParagraphs.d.ts +15 -0
  177. package/dist/editor/plugins/styledParagraphs.js +65 -0
  178. package/dist/editor/plugins/tabCaret.d.ts +3 -0
  179. package/dist/editor/plugins/tabCaret.js +126 -0
  180. package/dist/editor/plugins/tabDecorations.d.ts +11 -0
  181. package/dist/editor/plugins/tabDecorations.js +87 -0
  182. package/dist/editor/plugins/tabLayout.d.ts +16 -0
  183. package/dist/editor/plugins/tabLayout.js +328 -0
  184. package/dist/editor/plugins/tabPointer.d.ts +7 -0
  185. package/dist/editor/plugins/tabPointer.js +95 -0
  186. package/dist/editor/plugins/tableContextMenu.d.ts +21 -0
  187. package/dist/editor/plugins/tableContextMenu.js +88 -0
  188. package/dist/editor/plugins/textContextMenu.d.ts +15 -0
  189. package/dist/editor/plugins/textContextMenu.js +90 -0
  190. package/dist/editor/views/imageResize.d.ts +53 -0
  191. package/dist/editor/views/imageResize.js +167 -0
  192. package/dist/editor/views/runMarkView.d.ts +15 -0
  193. package/dist/editor/views/runMarkView.js +9 -0
  194. package/dist/editor/views/tableView.d.ts +24 -0
  195. package/dist/editor/views/tableView.js +32 -0
  196. package/dist/index.d.ts +44 -0
  197. package/dist/index.js +38 -0
  198. package/dist/model/format.d.ts +240 -0
  199. package/dist/model/format.js +305 -0
  200. package/dist/model/tabStops.d.ts +17 -0
  201. package/dist/model/tabStops.js +22 -0
  202. package/dist/numbering/listTemplate.d.ts +29 -0
  203. package/dist/numbering/listTemplate.js +83 -0
  204. package/dist/numbering/markers.d.ts +24 -0
  205. package/dist/numbering/markers.js +93 -0
  206. package/dist/numbering/parseNumbering.d.ts +65 -0
  207. package/dist/numbering/parseNumbering.js +116 -0
  208. package/dist/numbering/writeNumbering.d.ts +13 -0
  209. package/dist/numbering/writeNumbering.js +49 -0
  210. package/dist/ooxml/errors.d.ts +39 -0
  211. package/dist/ooxml/errors.js +21 -0
  212. package/dist/ooxml/image.d.ts +88 -0
  213. package/dist/ooxml/image.js +106 -0
  214. package/dist/ooxml/tabStops.d.ts +3 -0
  215. package/dist/ooxml/tabStops.js +51 -0
  216. package/dist/ooxml/units.d.ts +37 -0
  217. package/dist/ooxml/units.js +116 -0
  218. package/dist/ooxml/xml.d.ts +36 -0
  219. package/dist/ooxml/xml.js +89 -0
  220. package/dist/page/PageGuides.d.ts +16 -0
  221. package/dist/page/PageGuides.js +114 -0
  222. package/dist/page/measureBlocks.d.ts +25 -0
  223. package/dist/page/measureBlocks.js +80 -0
  224. package/dist/page/pageDecorations.d.ts +36 -0
  225. package/dist/page/pageDecorations.js +211 -0
  226. package/dist/page/pageLayout.d.ts +176 -0
  227. package/dist/page/pageLayout.js +157 -0
  228. package/dist/page/tableMeasurements.d.ts +10 -0
  229. package/dist/page/tableMeasurements.js +115 -0
  230. package/dist/page/usePageLayout.d.ts +57 -0
  231. package/dist/page/usePageLayout.js +141 -0
  232. package/dist/schema/docxSchema.d.ts +9 -0
  233. package/dist/schema/docxSchema.js +863 -0
  234. package/dist/schema/index.d.ts +2 -0
  235. package/dist/schema/index.js +9 -0
  236. package/dist/schema/locks.d.ts +112 -0
  237. package/dist/schema/locks.js +211 -0
  238. package/dist/schema/rendering.d.ts +6 -0
  239. package/dist/schema/rendering.js +46 -0
  240. package/dist/styles/classNames.d.ts +214 -0
  241. package/dist/styles/classNames.js +208 -0
  242. package/dist/styles/colors.d.ts +11 -0
  243. package/dist/styles/colors.js +14 -0
  244. package/dist/styles/fontSizes.d.ts +6 -0
  245. package/dist/styles/fontSizes.js +20 -0
  246. package/dist/styles/fontStack.d.ts +55 -0
  247. package/dist/styles/fontStack.js +262 -0
  248. package/dist/styles/fonts.d.ts +6 -0
  249. package/dist/styles/fonts.js +11 -0
  250. package/dist/styles/inlineStyle.d.ts +67 -0
  251. package/dist/styles/inlineStyle.js +212 -0
  252. package/dist/styles/lineSpacings.d.ts +11 -0
  253. package/dist/styles/lineSpacings.js +10 -0
  254. package/dist/styles.css +1650 -0
  255. package/dist/table/cellBorders.d.ts +12 -0
  256. package/dist/table/cellBorders.js +9 -0
  257. package/dist/table/cellFormatting.d.ts +57 -0
  258. package/dist/table/cellFormatting.js +173 -0
  259. package/dist/table/columns.d.ts +25 -0
  260. package/dist/table/columns.js +155 -0
  261. package/dist/table/commands.d.ts +19 -0
  262. package/dist/table/commands.js +63 -0
  263. package/dist/table/format.d.ts +35 -0
  264. package/dist/table/format.js +26 -0
  265. package/dist/table/gridBorders.d.ts +42 -0
  266. package/dist/table/gridBorders.js +192 -0
  267. package/dist/table/index.d.ts +16 -0
  268. package/dist/table/index.js +52 -0
  269. package/dist/table/merge.d.ts +36 -0
  270. package/dist/table/merge.js +125 -0
  271. package/dist/table/resize.d.ts +55 -0
  272. package/dist/table/resize.js +66 -0
  273. package/dist/table/rowResize.d.ts +14 -0
  274. package/dist/table/rowResize.js +44 -0
  275. package/dist/table/rows.d.ts +32 -0
  276. package/dist/table/rows.js +89 -0
  277. package/dist/table/widths.d.ts +69 -0
  278. package/dist/table/widths.js +97 -0
  279. package/dist/ui/AlignMenu.d.ts +15 -0
  280. package/dist/ui/AlignMenu.js +64 -0
  281. package/dist/ui/CellStyleGroup.d.ts +15 -0
  282. package/dist/ui/CellStyleGroup.js +232 -0
  283. package/dist/ui/ColorPicker.d.ts +13 -0
  284. package/dist/ui/ColorPicker.js +165 -0
  285. package/dist/ui/CommentsPanel.d.ts +15 -0
  286. package/dist/ui/CommentsPanel.js +348 -0
  287. package/dist/ui/FontFamilySelect.d.ts +14 -0
  288. package/dist/ui/FontFamilySelect.js +59 -0
  289. package/dist/ui/FontSizeSelect.d.ts +11 -0
  290. package/dist/ui/FontSizeSelect.js +49 -0
  291. package/dist/ui/InsertImageButton.d.ts +9 -0
  292. package/dist/ui/InsertImageButton.js +47 -0
  293. package/dist/ui/LinkCard.d.ts +12 -0
  294. package/dist/ui/LinkCard.js +127 -0
  295. package/dist/ui/LinkPanel.d.ts +9 -0
  296. package/dist/ui/LinkPanel.js +121 -0
  297. package/dist/ui/MenuChoice.d.ts +11 -0
  298. package/dist/ui/MenuChoice.js +32 -0
  299. package/dist/ui/NotesPanel.d.ts +6 -0
  300. package/dist/ui/NotesPanel.js +33 -0
  301. package/dist/ui/ParagraphStyleSelect.d.ts +11 -0
  302. package/dist/ui/ParagraphStyleSelect.js +62 -0
  303. package/dist/ui/Popover.d.ts +22 -0
  304. package/dist/ui/Popover.js +74 -0
  305. package/dist/ui/SpacingMenu.d.ts +12 -0
  306. package/dist/ui/SpacingMenu.js +54 -0
  307. package/dist/ui/TableMenu.d.ts +12 -0
  308. package/dist/ui/TableMenu.js +112 -0
  309. package/dist/ui/TableSizePicker.d.ts +9 -0
  310. package/dist/ui/TableSizePicker.js +53 -0
  311. package/dist/ui/TextMenu.d.ts +15 -0
  312. package/dist/ui/TextMenu.js +194 -0
  313. package/dist/ui/Toolbar.d.ts +19 -0
  314. package/dist/ui/Toolbar.js +448 -0
  315. package/dist/ui/ToolbarButton.d.ts +23 -0
  316. package/dist/ui/ToolbarButton.js +56 -0
  317. package/dist/ui/Tooltip.d.ts +19 -0
  318. package/dist/ui/Tooltip.js +47 -0
  319. package/dist/ui/ZoomSelect.d.ts +7 -0
  320. package/dist/ui/ZoomSelect.js +44 -0
  321. package/dist/ui/comments/CommentComposer.d.ts +17 -0
  322. package/dist/ui/comments/CommentComposer.js +59 -0
  323. package/dist/ui/comments/useCommentRailLayout.d.ts +18 -0
  324. package/dist/ui/comments/useCommentRailLayout.js +183 -0
  325. package/dist/ui/keyboardWalk.d.ts +22 -0
  326. package/dist/ui/keyboardWalk.js +70 -0
  327. package/dist/ui/openAddress.d.ts +11 -0
  328. package/dist/ui/openAddress.js +16 -0
  329. package/dist/ui/panelPlacement.d.ts +51 -0
  330. package/dist/ui/panelPlacement.js +71 -0
  331. package/dist/ui/presets.d.ts +11 -0
  332. package/dist/ui/presets.js +0 -0
  333. package/dist/ui/rovingFocus.d.ts +20 -0
  334. package/dist/ui/rovingFocus.js +61 -0
  335. package/dist/ui/runCommand.d.ts +5 -0
  336. package/dist/ui/runCommand.js +13 -0
  337. package/dist/ui/useDismiss.d.ts +6 -0
  338. package/dist/ui/useDismiss.js +31 -0
  339. package/dist/ui/useFitWidthZoom.d.ts +2 -0
  340. package/dist/ui/useFitWidthZoom.js +26 -0
  341. package/dist/ui/useGridKeyboard.d.ts +12 -0
  342. package/dist/ui/useGridKeyboard.js +90 -0
  343. package/dist/ui/useMenuKeyboard.d.ts +12 -0
  344. package/dist/ui/useMenuKeyboard.js +56 -0
  345. package/dist/ui/zoom.d.ts +4 -0
  346. package/dist/ui/zoom.js +21 -0
  347. package/package.json +120 -0
@@ -0,0 +1,305 @@
1
+ // src/editor/commands/comments/editing.ts
2
+ import {
3
+ TextSelection
4
+ } from "prosemirror-state";
5
+ import { commentParaId } from "../../../docx/comments.js";
6
+ import { docxSchema } from "../../../schema/index.js";
7
+ import { transactionAllowed } from "../../../schema/locks.js";
8
+ import {
9
+ reservedCommentIds,
10
+ reservedCommentParaIds
11
+ } from "../../plugins/commentReservations.js";
12
+ import { documentComments, repliesAttr, stringAttr } from "./reading.js";
13
+ function validCommentSelection(state) {
14
+ const { selection } = state;
15
+ return selection instanceof TextSelection && !selection.empty && selection.$from.sameParent(selection.$to) && selection.$from.parent.type.name === "paragraph";
16
+ }
17
+ function nextCommentId(state) {
18
+ const taken = /* @__PURE__ */ new Set();
19
+ const reserve = (id) => {
20
+ if (!/^\d+$/.test(id)) return;
21
+ try {
22
+ taken.add(BigInt(id).toString());
23
+ } catch {
24
+ return;
25
+ }
26
+ };
27
+ for (const id of reservedCommentIds(state)) {
28
+ reserve(id);
29
+ }
30
+ state.doc.descendants((node) => {
31
+ if (node.type.name === "commentStart" || node.type.name === "commentEnd" || node.type.name === "commentReference") {
32
+ const id = stringAttr(node.attrs.id);
33
+ if (id !== null) reserve(id);
34
+ }
35
+ if (node.type.name === "commentReference") {
36
+ for (const reply of repliesAttr(node.attrs.replies)) {
37
+ reserve(reply.id);
38
+ }
39
+ }
40
+ return true;
41
+ });
42
+ let max = -1n;
43
+ for (const id of taken) {
44
+ const value = BigInt(id);
45
+ if (value > max) max = value;
46
+ }
47
+ return (max + 1n).toString();
48
+ }
49
+ function nextCommentParaId(state, seed, additional = []) {
50
+ const taken = new Set(
51
+ Array.from(reservedCommentParaIds(state), (id) => id.toUpperCase())
52
+ );
53
+ state.doc.descendants((node) => {
54
+ if (node.type.name !== "commentReference") return true;
55
+ const paraId = stringAttr(node.attrs.paraId);
56
+ if (paraId !== null) taken.add(paraId.toUpperCase());
57
+ for (const reply of repliesAttr(node.attrs.replies)) {
58
+ taken.add(reply.paraId.toUpperCase());
59
+ }
60
+ return true;
61
+ });
62
+ for (const paraId of additional) taken.add(paraId.toUpperCase());
63
+ let candidate = Number.parseInt(commentParaId(seed), 16);
64
+ while (taken.has(candidate.toString(16).toUpperCase().padStart(8, "0"))) {
65
+ candidate = candidate === 2147483647 ? 1 : candidate + 1;
66
+ }
67
+ return candidate.toString(16).toUpperCase().padStart(8, "0");
68
+ }
69
+ function wrapperMarksAt(state, pos, side) {
70
+ const resolved = state.doc.resolve(pos);
71
+ const adjacent = side === "before" ? resolved.nodeBefore : resolved.nodeAfter;
72
+ return (adjacent?.marks ?? resolved.marks()).filter(
73
+ (mark) => mark.type.name === "sdt" || mark.type.name === "link"
74
+ );
75
+ }
76
+ function addCommentTransaction(state, comment) {
77
+ if (!validCommentSelection(state) || comment.text.trim().length === 0) {
78
+ return null;
79
+ }
80
+ const id = nextCommentId(state);
81
+ const date = comment.date ?? (/* @__PURE__ */ new Date()).toISOString();
82
+ const paraId = nextCommentParaId(state, `comment-${id}-${date}`);
83
+ const { from, to } = state.selection;
84
+ const startMarks = wrapperMarksAt(state, from, "after");
85
+ const endMarks = wrapperMarksAt(state, to, "before");
86
+ const end = docxSchema.nodes.commentEnd.create(
87
+ { id, xml: null },
88
+ null,
89
+ endMarks
90
+ );
91
+ const reference = docxSchema.nodes.commentReference.create(
92
+ {
93
+ id,
94
+ referenceXml: null,
95
+ author: comment.author,
96
+ initials: comment.initials ?? null,
97
+ date,
98
+ text: comment.text,
99
+ commentXml: null,
100
+ imported: false,
101
+ paraId,
102
+ resolved: false,
103
+ extensionXml: null,
104
+ threadImported: true,
105
+ replies: []
106
+ },
107
+ null,
108
+ endMarks
109
+ );
110
+ const start = docxSchema.nodes.commentStart.create(
111
+ { id, xml: null },
112
+ null,
113
+ startMarks
114
+ );
115
+ const transaction = state.tr.insert(to, end).insert(to + 1, reference).insert(from, start);
116
+ return transactionAllowed(transaction, state.doc) ? transaction : null;
117
+ }
118
+ function canAddComment(state) {
119
+ return addCommentTransaction(state, {
120
+ text: "comment",
121
+ author: "Author",
122
+ date: "1970-01-01T00:00:00.000Z"
123
+ }) !== null;
124
+ }
125
+ function addComment(comment) {
126
+ return (state, dispatch) => {
127
+ const transaction = addCommentTransaction(state, comment);
128
+ if (!transaction) return false;
129
+ dispatch?.(transaction);
130
+ return true;
131
+ };
132
+ }
133
+ function updateComment(id, text) {
134
+ return (state, dispatch) => {
135
+ if (text.trim().length === 0) return false;
136
+ let transaction = state.tr;
137
+ let changed = false;
138
+ state.doc.descendants((node, pos) => {
139
+ if (node.type.name === "commentReference" && stringAttr(node.attrs.id) === id && stringAttr(node.attrs.text) !== text) {
140
+ transaction = transaction.setNodeMarkup(pos, null, {
141
+ ...node.attrs,
142
+ text,
143
+ commentXml: null,
144
+ imported: false
145
+ });
146
+ changed = true;
147
+ }
148
+ return true;
149
+ });
150
+ if (!changed || !transactionAllowed(transaction, state.doc)) return false;
151
+ dispatch?.(transaction);
152
+ return true;
153
+ };
154
+ }
155
+ function updateReference(id, change) {
156
+ return (state, dispatch) => {
157
+ let transaction = state.tr;
158
+ let changed = false;
159
+ state.doc.descendants((node, pos) => {
160
+ if (node.type.name !== "commentReference" || stringAttr(node.attrs.id) !== id) {
161
+ return true;
162
+ }
163
+ const attrs = change(node);
164
+ if (attrs !== null) {
165
+ transaction = transaction.setNodeMarkup(pos, null, attrs);
166
+ changed = true;
167
+ }
168
+ return false;
169
+ });
170
+ if (!changed || !transactionAllowed(transaction, state.doc)) return false;
171
+ dispatch?.(transaction);
172
+ return true;
173
+ };
174
+ }
175
+ function setCommentResolved(id, resolved) {
176
+ return (state, dispatch) => updateReference(id, (node) => {
177
+ if (node.attrs.resolved === resolved) return null;
178
+ return {
179
+ ...node.attrs,
180
+ paraId: node.attrs.threadImported === true && node.attrs.extensionXml === null ? nextCommentParaId(state, `comment-${id}`) : node.attrs.paraId,
181
+ resolved,
182
+ extensionXml: null,
183
+ threadImported: false,
184
+ imported: node.attrs.commentXml !== null && node.attrs.extensionXml === null ? false : node.attrs.imported
185
+ };
186
+ })(state, dispatch);
187
+ }
188
+ function addCommentReply(id, reply) {
189
+ return (state, dispatch) => {
190
+ if (reply.text.trim().length === 0) return false;
191
+ const replyId = nextCommentId(state);
192
+ const date = reply.date ?? (/* @__PURE__ */ new Date()).toISOString();
193
+ return updateReference(id, (node) => {
194
+ const parentParaId = node.attrs.threadImported === true && node.attrs.extensionXml === null ? nextCommentParaId(state, `comment-${id}`) : stringAttr(node.attrs.paraId) ?? nextCommentParaId(state, `comment-${id}`);
195
+ const paraId = nextCommentParaId(state, `comment-${replyId}-${date}`, [
196
+ parentParaId
197
+ ]);
198
+ return {
199
+ ...node.attrs,
200
+ paraId: parentParaId,
201
+ resolved: false,
202
+ extensionXml: null,
203
+ threadImported: false,
204
+ imported: node.attrs.commentXml !== null && node.attrs.extensionXml === null ? false : node.attrs.imported,
205
+ replies: [
206
+ ...repliesAttr(node.attrs.replies),
207
+ {
208
+ id: replyId,
209
+ author: reply.author,
210
+ initials: reply.initials ?? null,
211
+ date,
212
+ text: reply.text,
213
+ commentXml: null,
214
+ imported: false,
215
+ paraId,
216
+ parentParaId,
217
+ extensionXml: null
218
+ }
219
+ ]
220
+ };
221
+ })(state, dispatch);
222
+ };
223
+ }
224
+ function updateCommentReply(commentId, replyId, text) {
225
+ return updateReference(commentId, (node) => {
226
+ if (text.trim().length === 0) return null;
227
+ const replies = repliesAttr(node.attrs.replies);
228
+ const index = replies.findIndex((reply) => reply.id === replyId);
229
+ if (index < 0 || replies[index].text === text) return null;
230
+ return {
231
+ ...node.attrs,
232
+ replies: replies.map(
233
+ (reply, at) => at === index ? { ...reply, text, commentXml: null, imported: false } : reply
234
+ )
235
+ };
236
+ });
237
+ }
238
+ function removeCommentReply(commentId, replyId) {
239
+ return updateReference(commentId, (node) => {
240
+ const replies = repliesAttr(node.attrs.replies);
241
+ if (!replies.some((reply) => reply.id === replyId)) return null;
242
+ const removedIds = /* @__PURE__ */ new Set([replyId]);
243
+ const removedParaIds = new Set(
244
+ replies.filter((reply) => removedIds.has(reply.id)).map((reply) => reply.paraId)
245
+ );
246
+ let changed = true;
247
+ while (changed) {
248
+ changed = false;
249
+ for (const reply of replies) {
250
+ if (!removedIds.has(reply.id) && removedParaIds.has(reply.parentParaId)) {
251
+ removedIds.add(reply.id);
252
+ removedParaIds.add(reply.paraId);
253
+ changed = true;
254
+ }
255
+ }
256
+ }
257
+ return {
258
+ ...node.attrs,
259
+ replies: replies.filter((reply) => !removedIds.has(reply.id)),
260
+ threadImported: false
261
+ };
262
+ });
263
+ }
264
+ function removeComment(id) {
265
+ return (state, dispatch) => {
266
+ const positions = [];
267
+ state.doc.descendants((node, pos) => {
268
+ if ((node.type.name === "commentStart" || node.type.name === "commentEnd" || node.type.name === "commentReference") && stringAttr(node.attrs.id) === id) {
269
+ positions.push({ pos, size: node.nodeSize });
270
+ }
271
+ return true;
272
+ });
273
+ if (positions.length === 0) return false;
274
+ const transaction = state.tr;
275
+ for (const marker of positions.sort((a, b) => b.pos - a.pos)) {
276
+ transaction.delete(marker.pos, marker.pos + marker.size);
277
+ }
278
+ if (!transactionAllowed(transaction, state.doc)) return false;
279
+ dispatch?.(transaction);
280
+ return true;
281
+ };
282
+ }
283
+ function selectComment(id) {
284
+ return (state, dispatch) => {
285
+ const comment = documentComments(state).find((entry) => entry.id === id);
286
+ if (!comment) return false;
287
+ dispatch?.(
288
+ state.tr.setSelection(
289
+ TextSelection.create(state.doc, comment.from, comment.to)
290
+ )
291
+ );
292
+ return true;
293
+ };
294
+ }
295
+ export {
296
+ addComment,
297
+ addCommentReply,
298
+ canAddComment,
299
+ removeComment,
300
+ removeCommentReply,
301
+ selectComment,
302
+ setCommentResolved,
303
+ updateComment,
304
+ updateCommentReply
305
+ };
@@ -0,0 +1,31 @@
1
+ /** Public comment values and shared attribute readers. */
2
+ export interface CommentAuthor {
3
+ name: string;
4
+ initials?: string;
5
+ }
6
+ export interface NewComment {
7
+ text: string;
8
+ author: string;
9
+ initials?: string;
10
+ /** ISO 8601 timestamp. The current time is used when omitted. */
11
+ date?: string;
12
+ }
13
+ export interface DocumentComment {
14
+ id: string;
15
+ author: string | null;
16
+ initials: string | null;
17
+ date: string | null;
18
+ text: string;
19
+ from: number;
20
+ to: number;
21
+ referencePos: number;
22
+ resolved: boolean;
23
+ replies: readonly DocumentCommentReply[];
24
+ }
25
+ export interface DocumentCommentReply {
26
+ id: string;
27
+ author: string | null;
28
+ initials: string | null;
29
+ date: string | null;
30
+ text: string;
31
+ }
File without changes
@@ -0,0 +1,8 @@
1
+ /** Reads comment threads and anchors from the editor document. */
2
+ import type { EditorState } from "prosemirror-state";
3
+ import type { CommentReplyData } from "../../../docx/comments";
4
+ import type { DocumentComment } from "./model";
5
+ export declare function stringAttr(value: unknown): string | null;
6
+ export declare function repliesAttr(value: unknown): readonly CommentReplyData[];
7
+ /** Comments in document order, including point comments that have no explicit range. */
8
+ export declare function documentComments(state: EditorState): readonly DocumentComment[];
@@ -0,0 +1,58 @@
1
+ // src/editor/commands/comments/reading.ts
2
+ function stringAttr(value) {
3
+ return typeof value === "string" ? value : null;
4
+ }
5
+ function repliesAttr(value) {
6
+ return Array.isArray(value) ? value : [];
7
+ }
8
+ function markerPositions(doc) {
9
+ const starts = /* @__PURE__ */ new Map();
10
+ const ends = /* @__PURE__ */ new Map();
11
+ const references = [];
12
+ doc.descendants((node, pos) => {
13
+ const id = stringAttr(node.attrs.id);
14
+ if (id === null) return true;
15
+ if (node.type.name === "commentStart" && !starts.has(id)) {
16
+ starts.set(id, pos);
17
+ } else if (node.type.name === "commentEnd" && !ends.has(id)) {
18
+ ends.set(id, pos);
19
+ } else if (node.type.name === "commentReference") {
20
+ references.push({ node, pos });
21
+ }
22
+ return true;
23
+ });
24
+ return { starts, ends, references };
25
+ }
26
+ function documentComments(state) {
27
+ const markers = markerPositions(state.doc);
28
+ return markers.references.map(({ node, pos }) => {
29
+ const id = stringAttr(node.attrs.id) ?? "";
30
+ const start = markers.starts.get(id);
31
+ const end = markers.ends.get(id);
32
+ const hasRange = start !== void 0 && end !== void 0 && start < end;
33
+ const point = start ?? end ?? pos;
34
+ return {
35
+ id,
36
+ author: stringAttr(node.attrs.author),
37
+ initials: stringAttr(node.attrs.initials),
38
+ date: stringAttr(node.attrs.date),
39
+ text: stringAttr(node.attrs.text) ?? "",
40
+ from: hasRange ? start + 1 : point,
41
+ to: hasRange ? end : point,
42
+ referencePos: pos,
43
+ resolved: node.attrs.resolved === true,
44
+ replies: repliesAttr(node.attrs.replies).map((reply) => ({
45
+ id: reply.id,
46
+ author: reply.author,
47
+ initials: reply.initials,
48
+ date: reply.date,
49
+ text: reply.text
50
+ }))
51
+ };
52
+ });
53
+ }
54
+ export {
55
+ documentComments,
56
+ repliesAttr,
57
+ stringAttr
58
+ };
@@ -0,0 +1,32 @@
1
+ /** Applies inline formatting while preserving each run's untouched XML. */
2
+ import type { Command, EditorState } from "prosemirror-state";
3
+ export type { RunToggle } from "../../../docx/runProps";
4
+ /**
5
+ * Whether character formatting reaches anything where the selection stands, which is what a
6
+ * control offering it is drawn from.
7
+ *
8
+ * A selection running over a lock keeps its say, because the locked pieces are left out rather
9
+ * than the whole edit refused; only a selection the lock leaves nothing of has nothing to format.
10
+ * A caret formats no text of its own - it stages the formatting for the text typed next - so what
11
+ * settles it is whether that text could go in at all.
12
+ */
13
+ export declare function canFormatText(state: EditorState): boolean;
14
+ export declare const toggleBold: Command;
15
+ export declare const toggleItalic: Command;
16
+ export declare const toggleUnderline: Command;
17
+ export declare const toggleStrike: Command;
18
+ /** Sets the font size in points. Null withdraws the setting and falls back to the document default */
19
+ export declare function setFontSize(pt: number | null): Command;
20
+ /** Sets the font by name. Null withdraws the setting and falls back to the document default font */
21
+ export declare function setFontFamily(name: string | null): Command;
22
+ /** Sets the text color as `#RRGGBB`. Null withdraws the color setting */
23
+ export declare function setTextColor(hex: string | null): Command;
24
+ /**
25
+ * Sets the text background color as `#RRGGBB`. Null withdraws the background.
26
+ * A highlight (`w:highlight`) written by an older document is removed along with it at that spot.
27
+ */
28
+ export declare function setTextBackground(hex: string | null): Command;
29
+ export declare function isBoldActive(state: EditorState): boolean;
30
+ export declare function isItalicActive(state: EditorState): boolean;
31
+ export declare function isUnderlineActive(state: EditorState): boolean;
32
+ export declare function isStrikeActive(state: EditorState): boolean;
@@ -0,0 +1,138 @@
1
+ // src/editor/commands/formatting/editing.ts
2
+ import {
3
+ editRunProps,
4
+ isRunToggleOn,
5
+ matchesRunEdit
6
+ } from "../../../docx/runProps.js";
7
+ import { docxSchema } from "../../../schema/index.js";
8
+ import {
9
+ insertionInsideLocked,
10
+ rangeTouchesLocked
11
+ } from "../../../schema/locks.js";
12
+ import {
13
+ activePieces,
14
+ caretPiece,
15
+ text,
16
+ textPieces
17
+ } from "./shared.js";
18
+ function editedMark(target, edit) {
19
+ const next = editRunProps(
20
+ { rPr: text(target.mark?.attrs.rPr), format: target.format },
21
+ target.pPr,
22
+ edit
23
+ );
24
+ if (!next) return null;
25
+ return docxSchema.marks.run.create({
26
+ ...target.mark?.attrs,
27
+ rPr: next.rPr,
28
+ format: next.format
29
+ });
30
+ }
31
+ function planChanges(pieces, edit) {
32
+ const changes = [];
33
+ for (const target of pieces) {
34
+ const mark = editedMark(target, edit);
35
+ if (!mark) return null;
36
+ changes.push({ from: target.from, to: target.to, mark });
37
+ }
38
+ return changes;
39
+ }
40
+ function applyToSelection(state, dispatch, edit) {
41
+ const pieces = textPieces(state).filter(
42
+ (target) => (
43
+ // Text already in the desired state is left untouched, so its original XML survives
44
+ !matchesRunEdit(target.format, edit) && // A locked stretch is left out rather than refused: the guard turns down the whole
45
+ // transaction, so asking for it would leave the rest of the selection unformatted too
46
+ !rangeTouchesLocked(state.doc, target.from, target.to)
47
+ )
48
+ );
49
+ const changes = pieces.length > 0 ? planChanges(pieces, edit) : null;
50
+ if (!changes) return false;
51
+ if (dispatch) {
52
+ const tr = state.tr;
53
+ for (const change of changes) {
54
+ tr.addMark(change.from, change.to, change.mark);
55
+ }
56
+ dispatch(tr);
57
+ }
58
+ return true;
59
+ }
60
+ function applyToCaret(state, dispatch, edit) {
61
+ const target = caretPiece(state);
62
+ if (matchesRunEdit(target.format, edit)) return false;
63
+ const mark = editedMark(target, edit);
64
+ if (!mark) return false;
65
+ if (dispatch) {
66
+ const marks = state.storedMarks ?? state.selection.$from.marks();
67
+ dispatch(state.tr.setStoredMarks(mark.addToSet(marks)));
68
+ }
69
+ return true;
70
+ }
71
+ function runEditCommand(edit) {
72
+ return (state, dispatch) => state.selection.empty ? applyToCaret(state, dispatch, edit) : applyToSelection(state, dispatch, edit);
73
+ }
74
+ function canFormatText(state) {
75
+ if (state.selection.empty) {
76
+ return !insertionInsideLocked(state.doc, state.selection.from);
77
+ }
78
+ return textPieces(state).some(
79
+ (target) => !rangeTouchesLocked(state.doc, target.from, target.to)
80
+ );
81
+ }
82
+ function isToggleActive(state, toggle) {
83
+ const pieces = activePieces(state);
84
+ return pieces.length > 0 && pieces.every((target) => isRunToggleOn(target.format, toggle));
85
+ }
86
+ function toggleCommand(toggle) {
87
+ return (state, dispatch) => {
88
+ const edit = {
89
+ kind: "toggle",
90
+ toggle,
91
+ on: !isToggleActive(state, toggle)
92
+ };
93
+ return runEditCommand(edit)(state, dispatch);
94
+ };
95
+ }
96
+ var toggleBold = toggleCommand("bold");
97
+ var toggleItalic = toggleCommand("italic");
98
+ var toggleUnderline = toggleCommand("underline");
99
+ var toggleStrike = toggleCommand("strike");
100
+ function setFontSize(pt) {
101
+ return runEditCommand({ kind: "fontSize", pt });
102
+ }
103
+ function setFontFamily(name) {
104
+ return runEditCommand({ kind: "fontFamily", name });
105
+ }
106
+ function setTextColor(hex) {
107
+ return runEditCommand({ kind: "color", hex });
108
+ }
109
+ function setTextBackground(hex) {
110
+ return runEditCommand({ kind: "background", hex });
111
+ }
112
+ function isBoldActive(state) {
113
+ return isToggleActive(state, "bold");
114
+ }
115
+ function isItalicActive(state) {
116
+ return isToggleActive(state, "italic");
117
+ }
118
+ function isUnderlineActive(state) {
119
+ return isToggleActive(state, "underline");
120
+ }
121
+ function isStrikeActive(state) {
122
+ return isToggleActive(state, "strike");
123
+ }
124
+ export {
125
+ canFormatText,
126
+ isBoldActive,
127
+ isItalicActive,
128
+ isStrikeActive,
129
+ isUnderlineActive,
130
+ setFontFamily,
131
+ setFontSize,
132
+ setTextBackground,
133
+ setTextColor,
134
+ toggleBold,
135
+ toggleItalic,
136
+ toggleStrike,
137
+ toggleUnderline
138
+ };
@@ -0,0 +1,57 @@
1
+ /** Reads the active inline formatting shown by toolbar controls. */
2
+ import type { Node as PMNode } from "prosemirror-model";
3
+ import type { EditorState } from "prosemirror-state";
4
+ import { type DocumentDefaults } from "../../../model/format";
5
+ import { type FontFallbacks } from "../../../styles/fontStack";
6
+ /**
7
+ * The font size at the selected position.
8
+ *
9
+ * "nobody wrote down a size" is kept apart from "several sizes are mixed".
10
+ * Lumping the two together would leave the toolbar unable to tell which is which, and both
11
+ * would show as the default value.
12
+ */
13
+ export type ActiveFontSize =
14
+ /** Every selected character has the same size. A size given by a paragraph style lands here too */
15
+ {
16
+ kind: "size";
17
+ pt: number;
18
+ }
19
+ /** Nobody wrote down a size, so `pt` is the size that actually gets rendered */
20
+ | {
21
+ kind: "default";
22
+ pt: number;
23
+ }
24
+ /** There are several sizes */
25
+ | {
26
+ kind: "mixed";
27
+ };
28
+ export declare function activeFontSize(state: EditorState): ActiveFontSize;
29
+ /**
30
+ * The font at the selected position.
31
+ * The same three branches as size: explicit, unspecified (the name that actually gets rendered),
32
+ * and mixed.
33
+ */
34
+ export type ActiveFontFamily =
35
+ /** Every selected character has the same font. A font given by a paragraph style lands here too */
36
+ {
37
+ kind: "font";
38
+ name: string;
39
+ }
40
+ /** Nobody wrote down a font, so `name` is the font that actually gets rendered */
41
+ | {
42
+ kind: "default";
43
+ name: string;
44
+ }
45
+ /** There are several fonts */
46
+ | {
47
+ kind: "mixed";
48
+ };
49
+ export declare function activeFontFamily(state: EditorState, fontFallbacks?: FontFallbacks): ActiveFontFamily;
50
+ /**
51
+ * Every font name this document uses. Collects the document default font and the fonts the
52
+ * runs wrote down. The toolbar select appends them after its presets.
53
+ * This walks the whole document, so the caller only calls it when the document changes.
54
+ */
55
+ export declare function documentFontNames(doc: PMNode, defaults: DocumentDefaults): string[];
56
+ export declare function activeTextColor(state: EditorState): string | null;
57
+ export declare function activeTextBackground(state: EditorState): string | null;