@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,44 @@
1
+ // src/editor/insertTable.ts
2
+ import { Fragment } from "prosemirror-model";
3
+ import {
4
+ TextSelection
5
+ } from "prosemirror-state";
6
+ import { createTableNode, isTableSide } from "../docx/tableTemplate.js";
7
+ import { documentGeometry } from "./documentStyles.js";
8
+ function isInTable($pos) {
9
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
10
+ if ($pos.node(depth).type.spec.tableRole === "table") return true;
11
+ }
12
+ return false;
13
+ }
14
+ function insertPosition(state) {
15
+ const $from = state.selection.$from;
16
+ if ($from.depth === 0 || isInTable($from)) return null;
17
+ return $from.after(1);
18
+ }
19
+ function canInsertTable(state) {
20
+ return insertPosition(state) !== null;
21
+ }
22
+ function insertTable({ rows, columns }) {
23
+ return (state, dispatch) => {
24
+ const at = insertPosition(state);
25
+ if (at === null || !isTableSide(rows) || !isTableSide(columns))
26
+ return false;
27
+ if (dispatch) {
28
+ const tr = state.tr.insert(
29
+ at,
30
+ Fragment.fromArray([
31
+ createTableNode(rows, columns, documentGeometry(state)),
32
+ state.schema.nodes.paragraph.create()
33
+ ])
34
+ );
35
+ const selection = TextSelection.near(tr.doc.resolve(at + 1));
36
+ dispatch(tr.setSelection(selection).scrollIntoView());
37
+ }
38
+ return true;
39
+ };
40
+ }
41
+ export {
42
+ canInsertTable,
43
+ insertTable
44
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The shared path that swaps the formatting fragments of the selected paragraphs in a single
3
+ * transaction.
4
+ *
5
+ * All this file takes on is which paragraphs to edit and how to write the new fragments in.
6
+ * How to edit a fragment is decided by the caller (lists, alignment), and the XML surgery is
7
+ * done by `docx/paraProps`.
8
+ */
9
+ import type { Node as PMNode } from "prosemirror-model";
10
+ import type { EditorState, Transaction } from "prosemirror-state";
11
+ import { type StyleTable } from "../docx/formatting";
12
+ import type { ParagraphProps } from "../docx/paraProps";
13
+ export interface ParagraphSpot {
14
+ pos: number;
15
+ node: PMNode;
16
+ }
17
+ /** The paragraphs the selection spans. Selections covering several table cells are handled too */
18
+ export declare function selectedParagraphs(state: EditorState): ParagraphSpot[];
19
+ /**
20
+ * The selected paragraphs a lock leaves editable, which is what every paragraph edit works on.
21
+ *
22
+ * A locked stretch is left out rather than the whole edit refused, the policy character formatting
23
+ * already follows (`commands/formattingCommands`): the guard turns down a whole transaction, so
24
+ * asking for it would leave the rest of the selection unedited too. A selection the lock leaves
25
+ * nothing of edits nothing, and the command reports that of its own accord, which is the disabled
26
+ * state of the control that runs it.
27
+ *
28
+ * Only the paragraphs of a locked cell are shut. A paragraph merely holding a locked control keeps
29
+ * its own alignment, indent and style, which is what `insideLockedCell` says and
30
+ * `rangeTouchesLocked` would not (`schema/locks`).
31
+ */
32
+ export declare function editableParagraphs(state: EditorState): ParagraphSpot[];
33
+ /** The original formatting XML this paragraph holds. Null when there is none */
34
+ export declare function paragraphPPr(node: PMNode): string | null;
35
+ /**
36
+ * How to edit a single paragraph. Null skips that paragraph.
37
+ * The style table and the document's default paragraph style come along, because the display values
38
+ * of the edited fragment are read back with the style the paragraph wears laid underneath.
39
+ */
40
+ export type ParagraphSurgery = (node: PMNode, styles: StyleTable, defaultStyleId: string | null) => ParagraphProps | null;
41
+ /** Edits the selected paragraphs in a single transaction. Does nothing when there is nothing to edit */
42
+ export declare function editParagraphs(state: EditorState, dispatch: ((tr: Transaction) => void) | undefined, surgery: ParagraphSurgery): boolean;
@@ -0,0 +1,59 @@
1
+ // src/editor/paragraphEdits.ts
2
+ import { effectiveParagraphFormat } from "../docx/formatting.js";
3
+ import { docxSchema } from "../schema/index.js";
4
+ import { insideLockedCell } from "../schema/locks.js";
5
+ import {
6
+ defaultParagraphStyleId,
7
+ documentParagraphFormatting,
8
+ documentStyles
9
+ } from "./documentStyles.js";
10
+ function selectedParagraphs(state) {
11
+ const spots = /* @__PURE__ */ new Map();
12
+ for (const range of state.selection.ranges) {
13
+ state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
14
+ if (node.type !== docxSchema.nodes.paragraph) return true;
15
+ spots.set(pos, node);
16
+ return false;
17
+ });
18
+ }
19
+ return Array.from(spots, ([pos, node]) => ({ pos, node }));
20
+ }
21
+ function editableParagraphs(state) {
22
+ return selectedParagraphs(state).filter(
23
+ (spot) => !insideLockedCell(state.doc, spot.pos)
24
+ );
25
+ }
26
+ function paragraphPPr(node) {
27
+ const pPr = node.attrs.pPr;
28
+ return typeof pPr === "string" ? pPr : null;
29
+ }
30
+ function writeChanges(state, changed) {
31
+ const tr = state.tr;
32
+ const formatting = documentParagraphFormatting(state);
33
+ for (const { spot, props } of changed) {
34
+ tr.setNodeMarkup(tr.mapping.map(spot.pos), void 0, {
35
+ ...spot.node.attrs,
36
+ pPr: props.pPr,
37
+ format: effectiveParagraphFormat(props.pPr, formatting),
38
+ styleRun: props.styleRun
39
+ });
40
+ }
41
+ return tr;
42
+ }
43
+ function editParagraphs(state, dispatch, surgery) {
44
+ const styles = documentStyles(state);
45
+ const defaultStyleId = defaultParagraphStyleId(state);
46
+ const changed = editableParagraphs(state).flatMap((spot) => {
47
+ const props = surgery(spot.node, styles, defaultStyleId);
48
+ return props ? [{ spot, props }] : [];
49
+ });
50
+ if (changed.length === 0) return false;
51
+ if (dispatch) dispatch(writeChanges(state, changed).scrollIntoView());
52
+ return true;
53
+ }
54
+ export {
55
+ editParagraphs,
56
+ editableParagraphs,
57
+ paragraphPPr,
58
+ selectedParagraphs
59
+ };
@@ -0,0 +1,3 @@
1
+ import type { EditorView } from "prosemirror-view";
2
+ export declare function insertPlainText(view: EditorView, source: string): void;
3
+ export declare function insertPlainTextAt(view: EditorView, source: string, from: number, to: number): void;
@@ -0,0 +1,50 @@
1
+ // src/editor/plainText.ts
2
+ import { AllSelection, TextSelection } from "prosemirror-state";
3
+ import { docxSchema } from "../schema/index.js";
4
+ var AS_NODE = {
5
+ "\n": "hardBreak",
6
+ "\v": "hardBreak",
7
+ "\f": "hardBreak",
8
+ " ": "tab"
9
+ };
10
+ var SPLIT_AT = /([\n\u000B\u000C\t])/;
11
+ var FORBIDDEN = /[\u0000-\u0008\u000E-\u001F]/g;
12
+ function toPieces(source) {
13
+ return source.replace(/\r\n?/g, "\n").replace(FORBIDDEN, "").split(SPLIT_AT).flatMap((chunk) => {
14
+ const node = AS_NODE[chunk];
15
+ if (node) return [{ node }];
16
+ return chunk ? [{ text: chunk }] : [];
17
+ });
18
+ }
19
+ function insertWithSelection(view, source, selection) {
20
+ const pieces = toPieces(source);
21
+ if (pieces.length === 0) return;
22
+ const tr = view.state.tr.setSelection(selection);
23
+ for (const piece of pieces) {
24
+ if ("text" in piece) tr.insertText(piece.text);
25
+ else if (piece.node === "hardBreak") {
26
+ tr.replaceSelectionWith(docxSchema.nodes.hardBreak.create());
27
+ } else {
28
+ const marks = (tr.storedMarks ?? tr.selection.$from.marks()).filter(
29
+ (mark) => mark.type !== docxSchema.marks.tab
30
+ );
31
+ tr.replaceSelectionWith(
32
+ docxSchema.text(" ", docxSchema.marks.tab.create().addToSet(marks)),
33
+ false
34
+ );
35
+ }
36
+ }
37
+ view.dispatch(tr.scrollIntoView());
38
+ }
39
+ function insertPlainText(view, source) {
40
+ insertWithSelection(view, source, view.state.selection);
41
+ }
42
+ function insertPlainTextAt(view, source, from, to) {
43
+ const { doc } = view.state;
44
+ const selection = from === 0 && to === doc.content.size ? new AllSelection(doc) : TextSelection.between(doc.resolve(from), doc.resolve(to));
45
+ insertWithSelection(view, source, selection);
46
+ }
47
+ export {
48
+ insertPlainText,
49
+ insertPlainTextAt
50
+ };
@@ -0,0 +1,3 @@
1
+ /** Prevents ordinary editor transactions from dropping imported bookmark range markers. */
2
+ import { Plugin } from "prosemirror-state";
3
+ export declare function bookmarkProtection(): Plugin;
@@ -0,0 +1,28 @@
1
+ // src/editor/plugins/bookmarkProtection.ts
2
+ import { Plugin } from "prosemirror-state";
3
+ var BOOKMARK_XML = /<(?:[\w.-]+:)?bookmark(?:Start|End)\b/;
4
+ function signatures(doc) {
5
+ const found = [];
6
+ doc.descendants((node) => {
7
+ if (node.type.name === "bookmarkBlock") {
8
+ found.push(`block:${node.attrs.srcId}:${node.attrs.name}`);
9
+ } else if (node.type.name === "rawInline" && typeof node.attrs.xml === "string" && BOOKMARK_XML.test(node.attrs.xml)) {
10
+ found.push(`inline:${node.attrs.xml}`);
11
+ }
12
+ return true;
13
+ });
14
+ return found;
15
+ }
16
+ function same(a, b) {
17
+ return a.length === b.length && a.every((value, index) => value === b[index]);
18
+ }
19
+ function bookmarkProtection() {
20
+ return new Plugin({
21
+ filterTransaction(transaction, state) {
22
+ return !transaction.docChanged || same(signatures(state.doc), signatures(transaction.doc));
23
+ }
24
+ });
25
+ }
26
+ export {
27
+ bookmarkProtection
28
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Previews column-edge drags in the DOM and commits one dxa-based resize transaction on release.
3
+ * Escape or an interrupted drag restores the rendered widths without editing the document.
4
+ */
5
+ import { Plugin } from "prosemirror-state";
6
+ /** The grabbed edge. `col` is the grid column left of the edge, `side` is which side of the pressed cell that edge is */
7
+ export interface ColumnEdgeHit {
8
+ col: number;
9
+ side: "left" | "right";
10
+ }
11
+ /**
12
+ * Which vertical edge of a cell this horizontal position points at.
13
+ *
14
+ * A merged cell only grabs the outer edges of the grid columns it covers.
15
+ * The left end of the table is not grabbable because there is no column to move
16
+ * (that edge means table indentation, which is a different thing).
17
+ * We return the grabbed side as well so the guide line can stay glued to that side
18
+ * during the drag.
19
+ */
20
+ export declare function columnEdgeAt(clientX: number, cell: {
21
+ readonly left: number;
22
+ readonly right: number;
23
+ }, covered: {
24
+ readonly from: number;
25
+ readonly to: number;
26
+ }, tolerance?: number): ColumnEdgeHit | null;
27
+ export declare function columnResize(): Plugin;
@@ -0,0 +1,192 @@
1
+ // src/editor/plugins/columnResize.ts
2
+ import { Plugin } from "prosemirror-state";
3
+ import { TableMap } from "prosemirror-tables";
4
+ import { spanCount } from "../../model/format.js";
5
+ import { editorClassNames } from "../../styles/classNames.js";
6
+ import { columnWidthPx } from "../../styles/inlineStyle.js";
7
+ import {
8
+ buildResizeColumnTransaction,
9
+ maxGridTotal,
10
+ resizedGridCols
11
+ } from "../../table/resize.js";
12
+ import {
13
+ gridTotal,
14
+ shiftedTableWidth,
15
+ tableGridCols
16
+ } from "../../table/widths.js";
17
+ import { documentGeometry } from "../documentStyles.js";
18
+ import { TableNodeView } from "../views/tableView.js";
19
+ var EDGE_TOLERANCE_PX = 4;
20
+ var FALLBACK_DXA_PER_PX = 15;
21
+ function columnEdgeAt(clientX, cell, covered, tolerance = EDGE_TOLERANCE_PX) {
22
+ if (Math.abs(clientX - cell.right) <= tolerance) {
23
+ return { col: covered.to - 1, side: "right" };
24
+ }
25
+ if (Math.abs(clientX - cell.left) <= tolerance && covered.from > 0) {
26
+ return { col: covered.from - 1, side: "left" };
27
+ }
28
+ return null;
29
+ }
30
+ function cellSpotAt(view, td) {
31
+ const $pos = view.state.doc.resolve(view.posAtDOM(td, 0));
32
+ for (let depth = $pos.depth; depth > 1; depth -= 1) {
33
+ const cell = $pos.node(depth);
34
+ if (cell.type.spec.tableRole !== "cell") continue;
35
+ const table = $pos.node(depth - 2);
36
+ if (table.type.spec.tableRole !== "table") return null;
37
+ const tablePos = $pos.before(depth - 2);
38
+ const from = TableMap.get(table).colCount(
39
+ $pos.before(depth) - tablePos - 1
40
+ );
41
+ return { tablePos, table, from, to: from + spanCount(cell.attrs.colspan) };
42
+ }
43
+ return null;
44
+ }
45
+ function columnElements(tableDom) {
46
+ return Array.from(tableDom.querySelectorAll(":scope > colgroup > col"));
47
+ }
48
+ function edgeUnder(view, event) {
49
+ const node = event.target instanceof Node ? event.target : null;
50
+ const element = node instanceof Element ? node : node?.parentElement;
51
+ const td = element?.closest("td");
52
+ const tableDom = td?.closest("table");
53
+ if (!td || !tableDom || !view.dom.contains(td)) return null;
54
+ const spot = cellSpotAt(view, td);
55
+ if (!spot) return null;
56
+ const gridCols = tableGridCols(spot.table);
57
+ if (!gridCols || gridCols.length !== TableMap.get(spot.table).width) {
58
+ return null;
59
+ }
60
+ const hit = columnEdgeAt(event.clientX, td.getBoundingClientRect(), spot);
61
+ if (!hit || hit.col < 0 || hit.col >= gridCols.length) return null;
62
+ return { ...spot, ...hit, gridCols, tableDom, cellDom: td };
63
+ }
64
+ function dxaPerPx(gridCols, tableDom) {
65
+ const drawn = tableDom.getBoundingClientRect().width;
66
+ return drawn > 0 ? gridTotal(gridCols) / drawn : FALLBACK_DXA_PER_PX;
67
+ }
68
+ function createGuide() {
69
+ const guide = document.createElement("div");
70
+ guide.className = editorClassNames.columnResizeGuide;
71
+ document.body.appendChild(guide);
72
+ return guide;
73
+ }
74
+ function moveGuide(drag) {
75
+ const { cellDom, side, tableDom } = drag.target;
76
+ const table = tableDom.getBoundingClientRect();
77
+ drag.guide.style.left = `${cellDom.getBoundingClientRect()[side]}px`;
78
+ drag.guide.style.top = `${table.top}px`;
79
+ drag.guide.style.height = `${table.height}px`;
80
+ }
81
+ function showPreview(drag, gridCols) {
82
+ gridCols.forEach((dxa, at) => {
83
+ const col = drag.cols[at];
84
+ if (col) col.style.width = `${columnWidthPx(dxa)}px`;
85
+ });
86
+ const width = shiftedTableWidth(drag.target.table, gridCols);
87
+ if (width?.type === "dxa") {
88
+ drag.target.tableDom.style.width = `${columnWidthPx(width.twips)}px`;
89
+ }
90
+ moveGuide(drag);
91
+ }
92
+ function hidePreview(drag) {
93
+ drag.cols.forEach((col, at) => {
94
+ col.style.width = drag.colWidths[at] ?? "";
95
+ });
96
+ drag.target.tableDom.style.width = drag.tableWidth;
97
+ drag.guide.remove();
98
+ }
99
+ function columnResize() {
100
+ let drag = null;
101
+ function stop() {
102
+ if (!drag) return;
103
+ window.removeEventListener("mousemove", onMove, true);
104
+ window.removeEventListener("mouseup", onUp, true);
105
+ window.removeEventListener("keydown", onKey, true);
106
+ hidePreview(drag);
107
+ drag.view.dom.classList.remove(editorClassNames.columnResize);
108
+ drag = null;
109
+ }
110
+ function onMove(event) {
111
+ if (!drag) return;
112
+ event.preventDefault();
113
+ const { gridCols, col } = drag.target;
114
+ const moved = (event.clientX - drag.startX) * drag.dxaPerPx;
115
+ drag.width = gridCols[col] + Math.round(moved);
116
+ const preview = resizedGridCols(gridCols, col, drag.width, drag.maxTotal);
117
+ showPreview(drag, preview ?? gridCols);
118
+ }
119
+ function onUp() {
120
+ const current = drag;
121
+ if (!current) return;
122
+ stop();
123
+ const tr = buildResizeColumnTransaction(
124
+ current.view.state,
125
+ {
126
+ tablePos: current.target.tablePos,
127
+ col: current.target.col,
128
+ width: current.width
129
+ },
130
+ documentGeometry(current.view.state)
131
+ );
132
+ if (tr) current.view.dispatch(tr);
133
+ }
134
+ function onKey(event) {
135
+ if (event.key !== "Escape") return;
136
+ event.preventDefault();
137
+ stop();
138
+ }
139
+ function start(view, event) {
140
+ const target = edgeUnder(view, event);
141
+ if (!target) return false;
142
+ const cols = columnElements(target.tableDom);
143
+ if (cols.length !== target.gridCols.length) return false;
144
+ drag = {
145
+ view,
146
+ target,
147
+ maxTotal: maxGridTotal(target.table, documentGeometry(view.state)),
148
+ startX: event.clientX,
149
+ dxaPerPx: dxaPerPx(target.gridCols, target.tableDom),
150
+ cols,
151
+ colWidths: cols.map((col) => col.style.width),
152
+ tableWidth: target.tableDom.style.width,
153
+ guide: createGuide(),
154
+ width: target.gridCols[target.col]
155
+ };
156
+ moveGuide(drag);
157
+ view.dom.classList.add(editorClassNames.columnResize);
158
+ window.addEventListener("mousemove", onMove, true);
159
+ window.addEventListener("mouseup", onUp, true);
160
+ window.addEventListener("keydown", onKey, true);
161
+ return true;
162
+ }
163
+ return new Plugin({
164
+ view: () => ({ destroy: stop }),
165
+ props: {
166
+ // Keeping ProseMirror from reverting the colgroup the preview edited is all this view does
167
+ nodeViews: { table: (node) => new TableNodeView(node) },
168
+ handleDOMEvents: {
169
+ mousemove(view, event) {
170
+ if (drag) return false;
171
+ const over = view.editable && edgeUnder(view, event) !== null;
172
+ view.dom.classList.toggle(editorClassNames.columnResize, over);
173
+ return false;
174
+ },
175
+ mouseleave(view) {
176
+ if (!drag) view.dom.classList.remove(editorClassNames.columnResize);
177
+ return false;
178
+ },
179
+ mousedown(view, event) {
180
+ if (!view.editable || drag || event.button !== 0) return false;
181
+ if (!start(view, event)) return false;
182
+ event.preventDefault();
183
+ return true;
184
+ }
185
+ }
186
+ }
187
+ });
188
+ }
189
+ export {
190
+ columnEdgeAt,
191
+ columnResize
192
+ };
@@ -0,0 +1,3 @@
1
+ /** Draws the text ranges identified by Word comment markers. */
2
+ import { Plugin } from "prosemirror-state";
3
+ export declare function commentDecorations(): Plugin;
@@ -0,0 +1,23 @@
1
+ // src/editor/plugins/commentDecorations.ts
2
+ import { Plugin } from "prosemirror-state";
3
+ import { Decoration, DecorationSet } from "prosemirror-view";
4
+ import { editorClassNames } from "../../styles/classNames.js";
5
+ import { documentComments } from "../commands/commentCommands.js";
6
+ function commentDecorations() {
7
+ return new Plugin({
8
+ props: {
9
+ decorations(state) {
10
+ const decorations = documentComments(state).filter((comment) => comment.from < comment.to).map(
11
+ (comment) => Decoration.inline(comment.from, comment.to, {
12
+ class: editorClassNames.commentRange,
13
+ "data-comment-id": comment.id
14
+ })
15
+ );
16
+ return DecorationSet.create(state.doc, decorations);
17
+ }
18
+ }
19
+ });
20
+ }
21
+ export {
22
+ commentDecorations
23
+ };
@@ -0,0 +1,5 @@
1
+ /** Keeps identifiers from the opened Comments parts reserved for the lifetime of the editor state. */
2
+ import { type EditorState, Plugin } from "prosemirror-state";
3
+ export declare function commentReservations(ids: Iterable<string>, paraIds: Iterable<string>): Plugin;
4
+ export declare function reservedCommentIds(state: EditorState): ReadonlySet<string>;
5
+ export declare function reservedCommentParaIds(state: EditorState): ReadonlySet<string>;
@@ -0,0 +1,26 @@
1
+ // src/editor/plugins/commentReservations.ts
2
+ import { Plugin, PluginKey } from "prosemirror-state";
3
+ var commentReservationsKey = new PluginKey(
4
+ "docxCommentReservations"
5
+ );
6
+ function commentReservations(ids, paraIds) {
7
+ const reserved = { ids: new Set(ids), paraIds: new Set(paraIds) };
8
+ return new Plugin({
9
+ key: commentReservationsKey,
10
+ state: {
11
+ init: () => reserved,
12
+ apply: (_transaction, value) => value
13
+ }
14
+ });
15
+ }
16
+ function reservedCommentIds(state) {
17
+ return commentReservationsKey.getState(state)?.ids ?? /* @__PURE__ */ new Set();
18
+ }
19
+ function reservedCommentParaIds(state) {
20
+ return commentReservationsKey.getState(state)?.paraIds ?? /* @__PURE__ */ new Set();
21
+ }
22
+ export {
23
+ commentReservations,
24
+ reservedCommentIds,
25
+ reservedCommentParaIds
26
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Where a drop lands.
3
+ *
4
+ * Both plugins that accept a drop from outside - plain text and image files - put what
5
+ * they insert at the caret, so the caret has to be moved to the spot the mouse let go of
6
+ * first.
7
+ */
8
+ import type { EditorView } from "prosemirror-view";
9
+ /** Moves the caret to the drop position. If that position cannot be found, the caret stays where it was */
10
+ export declare function moveCaretToDrop(view: EditorView, event: DragEvent): void;
@@ -0,0 +1,11 @@
1
+ // src/editor/plugins/dropCaret.ts
2
+ import { TextSelection } from "prosemirror-state";
3
+ function moveCaretToDrop(view, event) {
4
+ const spot = view.posAtCoords({ left: event.clientX, top: event.clientY });
5
+ if (!spot) return;
6
+ const selection = TextSelection.near(view.state.doc.resolve(spot.pos));
7
+ view.dispatch(view.state.tr.setSelection(selection));
8
+ }
9
+ export {
10
+ moveCaretToDrop
11
+ };
@@ -0,0 +1,8 @@
1
+ import { Plugin } from "prosemirror-state";
2
+ import { DecorationSet } from "prosemirror-view";
3
+ interface ImagePasteState {
4
+ decorations: DecorationSet;
5
+ cancelVersion: number;
6
+ }
7
+ export declare function imagePaste(): Plugin<ImagePasteState>;
8
+ export {};