@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,57 @@
1
+ /**
2
+ * Downloads the document the editor holds as a docx file.
3
+ *
4
+ * The pieces it is built out of are exported, but not from the package's barrel:
5
+ * `downloadDocx` is all a screen needs.
6
+ */
7
+ import type { Node as PMNode } from "prosemirror-model";
8
+ import type { DocxEditorHandle } from "./DocxEditor";
9
+ export declare const DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
10
+ export interface DownloadDocxOptions {
11
+ /** The name to save under. The `.docx` suffix may be there or not */
12
+ fileName: string;
13
+ }
14
+ export type DownloadDocxResult = {
15
+ status: "exported";
16
+ fileName: string;
17
+ byteLength: number;
18
+ } | {
19
+ status: "unavailable";
20
+ } | {
21
+ status: "empty";
22
+ };
23
+ /** Settles the end of the name on exactly one `.docx` */
24
+ export declare function withDocxExtension(fileName: string): string;
25
+ /**
26
+ * Wraps the docx bytes into a single file blob.
27
+ * A `Uint8Array` may be one slice of a larger buffer, so a copy is handed over.
28
+ */
29
+ export declare function createDocxBlob(bytes: Uint8Array): Blob;
30
+ /**
31
+ * Downloads a single file blob.
32
+ *
33
+ * The anchor is attached to the document and then taken off again because some
34
+ * browsers only honor the click while it is attached.
35
+ * Revoking the objectURL is deferred by `REVOKE_DELAY_MS`.
36
+ */
37
+ export declare function downloadBlob(blob: Blob, fileName: string): void;
38
+ /**
39
+ * Whether there is anything worth exporting.
40
+ *
41
+ * Any text counts as content, and so does a block that shows on screen without text of
42
+ * its own (a table, a placeholder).
43
+ * A document of nothing but empty paragraphs would download as a file with nothing to
44
+ * open, so it is taken to be empty.
45
+ */
46
+ export declare function hasExportableContent(doc: PMNode): boolean;
47
+ /**
48
+ * Downloads the edited document as a docx file.
49
+ *
50
+ * `unavailable` when the editor is not mounted yet or the document could not be
51
+ * opened, `empty` when there is nothing to export, and `exported` once a file has
52
+ * gone out.
53
+ * If writing the document back is blocked (a new list in a document without
54
+ * numbering.xml, and the like), it is not passed over silently: `DocxExportError`
55
+ * is rethrown as is.
56
+ */
57
+ export declare function downloadDocx(editor: DocxEditorHandle | null | undefined, options: DownloadDocxOptions): DownloadDocxResult;
@@ -0,0 +1,44 @@
1
+ // src/download.ts
2
+ var DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
3
+ var REVOKE_DELAY_MS = 6e4;
4
+ function withDocxExtension(fileName) {
5
+ return `${fileName.replace(/\.docx$/i, "")}.docx`;
6
+ }
7
+ function createDocxBlob(bytes) {
8
+ return new Blob([new Uint8Array(bytes)], { type: DOCX_MIME_TYPE });
9
+ }
10
+ function downloadBlob(blob, fileName) {
11
+ const url = URL.createObjectURL(blob);
12
+ const anchor = document.createElement("a");
13
+ anchor.href = url;
14
+ anchor.download = fileName;
15
+ anchor.rel = "noopener";
16
+ document.body.append(anchor);
17
+ anchor.click();
18
+ anchor.remove();
19
+ setTimeout(() => URL.revokeObjectURL(url), REVOKE_DELAY_MS);
20
+ }
21
+ function hasExportableContent(doc) {
22
+ if (doc.textContent.length > 0) return true;
23
+ let visible = false;
24
+ doc.forEach((block) => {
25
+ if (block.type.name !== "paragraph") visible = true;
26
+ });
27
+ return visible;
28
+ }
29
+ function downloadDocx(editor, options) {
30
+ if (!editor) return { status: "unavailable" };
31
+ if (!hasExportableContent(editor.view.state.doc)) return { status: "empty" };
32
+ const bytes = editor.exportBytes();
33
+ const fileName = withDocxExtension(options.fileName);
34
+ downloadBlob(createDocxBlob(bytes), fileName);
35
+ return { status: "exported", fileName, byteLength: bytes.length };
36
+ }
37
+ export {
38
+ DOCX_MIME_TYPE,
39
+ createDocxBlob,
40
+ downloadBlob,
41
+ downloadDocx,
42
+ hasExportableContent,
43
+ withDocxExtension
44
+ };
@@ -0,0 +1,14 @@
1
+ import type { ImageToInsert } from "../insertImage";
2
+ export declare const PASTED_IMAGE_ATTRIBUTE = "data-docx-pasted-image";
3
+ export interface ResolvedClipboardImages {
4
+ source: string;
5
+ images: ReadonlyMap<string, ImageToInsert>;
6
+ }
7
+ interface ResolveOptions {
8
+ maxWidthPx: number;
9
+ maxHeightPx: number;
10
+ signal: AbortSignal;
11
+ }
12
+ export declare function hasResolvableClipboardImages(document: Document, source: string): boolean;
13
+ export declare function resolveClipboardImages(document: Document, source: string, options: ResolveOptions): Promise<ResolvedClipboardImages> | null;
14
+ export {};
@@ -0,0 +1,158 @@
1
+ // src/editor/clipboard/images.ts
2
+ import { MAX_IMAGE_BYTES } from "../../docx/media.js";
3
+ import { isImageMime, toImageExtent, toImageSrc } from "../../ooxml/image.js";
4
+ import { editorClassNames } from "../../styles/classNames.js";
5
+ import {
6
+ boundedImageSrc,
7
+ imageSourceByteLength,
8
+ readImageBlob,
9
+ readImageSource
10
+ } from "../imageFiles.js";
11
+ var PASTED_IMAGE_ATTRIBUTE = "data-docx-pasted-image";
12
+ function extentAttribute(element) {
13
+ if (!element.classList.contains(editorClassNames.image)) return null;
14
+ try {
15
+ return toImageExtent(
16
+ JSON.parse(element.getAttribute("data-extent") ?? "null")
17
+ );
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function fetchableUrl(source) {
23
+ try {
24
+ const url = new URL(source);
25
+ return ["blob:", "http:", "https:"].includes(url.protocol) ? url : null;
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+ function canResolve(element) {
31
+ const source = element.getAttribute("src") ?? "";
32
+ return toImageSrc(source) !== null || fetchableUrl(source) !== null;
33
+ }
34
+ function hasResolvableClipboardImages(document, source) {
35
+ const template = document.createElement("template");
36
+ template.innerHTML = source;
37
+ return Array.from(template.content.querySelectorAll("img")).some(canResolve);
38
+ }
39
+ function abortIfAsked(signal) {
40
+ if (signal.aborted)
41
+ throw new DOMException("Image paste aborted", "AbortError");
42
+ }
43
+ async function limitedImageBlob(response, signal, maxBytes) {
44
+ if (!response.ok) {
45
+ await response.body?.cancel();
46
+ return null;
47
+ }
48
+ const mime = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
49
+ if (!isImageMime(mime)) {
50
+ await response.body?.cancel();
51
+ return null;
52
+ }
53
+ const declaredSize = Number.parseInt(
54
+ response.headers.get("content-length") ?? "",
55
+ 10
56
+ );
57
+ if (Number.isFinite(declaredSize) && declaredSize > maxBytes) {
58
+ await response.body?.cancel();
59
+ return null;
60
+ }
61
+ const reader = response.body?.getReader();
62
+ if (!reader) return null;
63
+ const chunks = [];
64
+ let size = 0;
65
+ try {
66
+ while (true) {
67
+ abortIfAsked(signal);
68
+ const { done, value } = await reader.read();
69
+ if (done) break;
70
+ if (size + value.length > maxBytes) {
71
+ await reader.cancel();
72
+ return null;
73
+ }
74
+ const chunk = Uint8Array.from(value);
75
+ size += chunk.length;
76
+ chunks.push(chunk);
77
+ }
78
+ } catch (error) {
79
+ await reader.cancel().catch(() => void 0);
80
+ throw error;
81
+ }
82
+ const bytes = new Uint8Array(size);
83
+ let offset = 0;
84
+ for (const chunk of chunks) {
85
+ bytes.set(chunk, offset);
86
+ offset += chunk.length;
87
+ }
88
+ return new Blob([bytes], { type: mime });
89
+ }
90
+ async function resolveElement(element, options, maxBytes) {
91
+ abortIfAsked(options.signal);
92
+ const source = element.getAttribute("src") ?? "";
93
+ const alt = element.getAttribute("alt") || null;
94
+ const readOptions = {
95
+ maxWidthPx: options.maxWidthPx,
96
+ maxHeightPx: options.maxHeightPx,
97
+ preferredExtent: extentAttribute(element),
98
+ alt,
99
+ signal: options.signal
100
+ };
101
+ if (toImageSrc(source) !== null) {
102
+ const src = boundedImageSrc(source);
103
+ return src === null || imageSourceByteLength(src) > maxBytes ? null : readImageSource(src, readOptions);
104
+ }
105
+ const url = fetchableUrl(source);
106
+ if (url === null) return null;
107
+ const response = await fetch(url, {
108
+ credentials: "omit",
109
+ referrerPolicy: "no-referrer",
110
+ signal: options.signal
111
+ });
112
+ const blob = await limitedImageBlob(response, options.signal, maxBytes);
113
+ return blob === null ? null : readImageBlob(blob, readOptions);
114
+ }
115
+ function replaceWithEditorImage(element, token) {
116
+ const replacement = element.ownerDocument.createElement("img");
117
+ replacement.setAttribute(PASTED_IMAGE_ATTRIBUTE, token);
118
+ element.replaceWith(replacement);
119
+ }
120
+ function resolveClipboardImages(document, source, options) {
121
+ const template = document.createElement("template");
122
+ template.innerHTML = source;
123
+ const elements = Array.from(template.content.querySelectorAll("img"));
124
+ for (const element of elements) {
125
+ element.removeAttribute(PASTED_IMAGE_ATTRIBUTE);
126
+ }
127
+ const images = elements.filter(canResolve);
128
+ if (images.length === 0) return null;
129
+ return (async () => {
130
+ let remainingBytes = MAX_IMAGE_BYTES;
131
+ const resolved = /* @__PURE__ */ new Map();
132
+ for (const element of images) {
133
+ abortIfAsked(options.signal);
134
+ let image = null;
135
+ try {
136
+ image = await resolveElement(element, options, remainingBytes);
137
+ } catch {
138
+ abortIfAsked(options.signal);
139
+ image = null;
140
+ }
141
+ const bytes = image && imageSourceByteLength(image.src);
142
+ if (image === null || bytes === null || bytes > remainingBytes) {
143
+ element.remove();
144
+ } else {
145
+ remainingBytes -= bytes;
146
+ const token = `${resolved.size}`;
147
+ resolved.set(token, image);
148
+ replaceWithEditorImage(element, token);
149
+ }
150
+ }
151
+ return { source: template.innerHTML, images: resolved };
152
+ })();
153
+ }
154
+ export {
155
+ PASTED_IMAGE_ATTRIBUTE,
156
+ hasResolvableClipboardImages,
157
+ resolveClipboardImages
158
+ };
@@ -0,0 +1,21 @@
1
+ import type { Mark, Node as PMNode } from "prosemirror-model";
2
+ export interface InlineStyle {
3
+ bold?: true;
4
+ italic?: true;
5
+ underline?: true;
6
+ strike?: true;
7
+ fontSizePt?: number;
8
+ fontFamily?: string;
9
+ color?: string;
10
+ background?: string;
11
+ }
12
+ export interface InlineContext {
13
+ style: InlineStyle;
14
+ href: string | null;
15
+ preserveWhitespace: boolean;
16
+ }
17
+ export type InlineElementReader = (target: PMNode[], element: HTMLElement, context: InlineContext) => boolean;
18
+ export declare function contextFor(parent: InlineContext, element: HTMLElement, readElementStyle?: boolean): InlineContext;
19
+ export declare function withInlineStyle(context: InlineContext, style: InlineStyle): InlineContext;
20
+ export declare function marksFor(context: InlineContext): Mark[];
21
+ export declare function appendInline(target: PMNode[], node: Node, context: InlineContext, readElement?: InlineElementReader): void;
@@ -0,0 +1,232 @@
1
+ // src/editor/clipboard/inlineFormatting.ts
2
+ import { editRunProps } from "../../docx/runProps.js";
3
+ import { docxSchema } from "../../schema/index.js";
4
+ import { editorClassNames } from "../../styles/classNames.js";
5
+ var IGNORED_TAGS = /* @__PURE__ */ new Set([
6
+ "HEAD",
7
+ "IFRAME",
8
+ "NOSCRIPT",
9
+ "OBJECT",
10
+ "SCRIPT",
11
+ "STYLE",
12
+ "TEMPLATE"
13
+ ]);
14
+ var GENERIC_FONTS = /* @__PURE__ */ new Set([
15
+ "cursive",
16
+ "fantasy",
17
+ "monospace",
18
+ "sans-serif",
19
+ "serif",
20
+ "system-ui"
21
+ ]);
22
+ var NAMED_COLORS = {
23
+ aqua: "#00ffff",
24
+ black: "#000000",
25
+ blue: "#0000ff",
26
+ fuchsia: "#ff00ff",
27
+ gray: "#808080",
28
+ green: "#008000",
29
+ lime: "#00ff00",
30
+ maroon: "#800000",
31
+ navy: "#000080",
32
+ olive: "#808000",
33
+ orange: "#ffa500",
34
+ purple: "#800080",
35
+ red: "#ff0000",
36
+ silver: "#c0c0c0",
37
+ teal: "#008080",
38
+ white: "#ffffff",
39
+ yellow: "#ffff00"
40
+ };
41
+ function cleanText(source, preserveWhitespace) {
42
+ const withoutForbidden = source.replace(/[\u000B\u000C]/g, "\n").replace(
43
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: XML 1.0 cannot hold these clipboard characters
44
+ /[\u0000-\u0008\u000E-\u001F]/g,
45
+ ""
46
+ );
47
+ return preserveWhitespace ? withoutForbidden.replace(/\r\n?/g, "\n") : withoutForbidden.replace(/[\t\n\v\f\r ]+/g, " ");
48
+ }
49
+ function cssHex(value) {
50
+ const source = value.trim().toLowerCase();
51
+ const named = NAMED_COLORS[source];
52
+ if (named) return named;
53
+ const short = /^#([0-9a-f]{3})$/.exec(source)?.[1];
54
+ if (short) {
55
+ return `#${short.split("").map((part) => `${part}${part}`).join("")}`;
56
+ }
57
+ const full = /^#([0-9a-f]{6})(?:ff)?$/.exec(source)?.[1];
58
+ if (full) return `#${full}`;
59
+ const rgb = /^rgba?\(\s*([\d.]+)[, ]+\s*([\d.]+)[, ]+\s*([\d.]+)(?:\s*[,/]\s*([\d.]+%?))?\s*\)$/.exec(
60
+ source
61
+ );
62
+ if (!rgb) return null;
63
+ const alpha = rgb[4];
64
+ if (alpha !== void 0) {
65
+ const opacity = Number.parseFloat(alpha);
66
+ if (alpha.endsWith("%") ? opacity < 100 : opacity < 1) return null;
67
+ }
68
+ const channels = rgb.slice(1, 4).map(
69
+ (part) => Math.max(0, Math.min(255, Math.round(Number.parseFloat(part ?? "0"))))
70
+ );
71
+ return `#${channels.map((part) => part.toString(16).padStart(2, "0")).join("")}`;
72
+ }
73
+ function fontSizePt(value) {
74
+ const match = /^([\d.]+)(pt|px)$/i.exec(value.trim());
75
+ if (!match) return null;
76
+ const amount = Number.parseFloat(match[1] ?? "");
77
+ if (!Number.isFinite(amount) || amount <= 0) return null;
78
+ const points = match[2]?.toLowerCase() === "px" ? amount * 0.75 : amount;
79
+ const rounded = Math.round(points * 2) / 2;
80
+ return rounded > 0 && rounded <= 819 ? rounded : null;
81
+ }
82
+ function legacyFontSize(value) {
83
+ const sizes = [8, 10, 12, 14, 18, 24, 36];
84
+ const index = Number.parseInt(value ?? "", 10) - 1;
85
+ return sizes[index] ?? null;
86
+ }
87
+ function firstFontFamily(value) {
88
+ const first = value.split(",", 1)[0]?.trim().replace(/^(['"])(.*)\1$/, "$2");
89
+ if (!first || GENERIC_FONTS.has(first.toLowerCase())) return null;
90
+ return first;
91
+ }
92
+ function toggle(style, key, on) {
93
+ if (on) style[key] = true;
94
+ else delete style[key];
95
+ }
96
+ function styleOf(parent, element) {
97
+ const style = { ...parent };
98
+ const tag = element.tagName;
99
+ if (tag === "B" || tag === "STRONG") style.bold = true;
100
+ if (tag === "I" || tag === "EM") style.italic = true;
101
+ if (tag === "U") style.underline = true;
102
+ if (tag === "S" || tag === "STRIKE" || tag === "DEL") style.strike = true;
103
+ if (tag === "MARK") style.background = "#ffff00";
104
+ const weight = element.style.fontWeight.trim().toLowerCase();
105
+ if (weight) {
106
+ const numeric = Number.parseInt(weight, 10);
107
+ toggle(
108
+ style,
109
+ "bold",
110
+ weight === "bold" || weight === "bolder" || numeric >= 600
111
+ );
112
+ }
113
+ const fontStyle = element.style.fontStyle.trim().toLowerCase();
114
+ if (fontStyle) {
115
+ toggle(style, "italic", fontStyle === "italic" || fontStyle === "oblique");
116
+ }
117
+ const decoration = (element.style.textDecorationLine || element.style.textDecoration).toLowerCase();
118
+ if (decoration) {
119
+ toggle(style, "underline", decoration.includes("underline"));
120
+ toggle(style, "strike", decoration.includes("line-through"));
121
+ }
122
+ const size = fontSizePt(element.style.fontSize) || (tag === "FONT" ? legacyFontSize(element.getAttribute("size")) : null);
123
+ if (size !== null) style.fontSizePt = size;
124
+ const family = firstFontFamily(
125
+ element.style.fontFamily || (tag === "FONT" ? element.getAttribute("face") ?? "" : "")
126
+ );
127
+ if (family !== null) style.fontFamily = family;
128
+ const color = cssHex(
129
+ element.style.color || (tag === "FONT" ? element.getAttribute("color") ?? "" : "")
130
+ );
131
+ if (color !== null) style.color = color;
132
+ const background = cssHex(element.style.backgroundColor);
133
+ if (background !== null) style.background = background;
134
+ return style;
135
+ }
136
+ function safeHref(value) {
137
+ const href = value?.trim() ?? "";
138
+ if (href === "") return null;
139
+ if (/^(?:https?|mailto|tel):/i.test(href)) return href;
140
+ return /^(?:[./]|#)/.test(href) ? href : null;
141
+ }
142
+ function contextFor(parent, element, readElementStyle = true) {
143
+ const copiedEditorLink = element.classList.contains(editorClassNames.link) ? element.getAttribute("data-href") : null;
144
+ return {
145
+ style: readElementStyle ? styleOf(parent.style, element) : parent.style,
146
+ href: element.tagName === "A" ? safeHref(element.getAttribute("href")) : safeHref(copiedEditorLink) ?? parent.href,
147
+ preserveWhitespace: parent.preserveWhitespace || element.tagName === "PRE"
148
+ };
149
+ }
150
+ function withInlineStyle(context, style) {
151
+ return { ...context, style: { ...context.style, ...style } };
152
+ }
153
+ function runMark(style) {
154
+ const edits = [];
155
+ if (style.bold) edits.push({ kind: "toggle", toggle: "bold", on: true });
156
+ if (style.italic) edits.push({ kind: "toggle", toggle: "italic", on: true });
157
+ if (style.underline) {
158
+ edits.push({ kind: "toggle", toggle: "underline", on: true });
159
+ }
160
+ if (style.strike) edits.push({ kind: "toggle", toggle: "strike", on: true });
161
+ if (style.fontSizePt !== void 0) {
162
+ edits.push({ kind: "fontSize", pt: style.fontSizePt });
163
+ }
164
+ if (style.fontFamily !== void 0) {
165
+ edits.push({ kind: "fontFamily", name: style.fontFamily });
166
+ }
167
+ if (style.color !== void 0)
168
+ edits.push({ kind: "color", hex: style.color });
169
+ if (style.background !== void 0) {
170
+ edits.push({ kind: "background", hex: style.background });
171
+ }
172
+ let props = {
173
+ rPr: null,
174
+ format: null
175
+ };
176
+ for (const edit of edits) {
177
+ const next = editRunProps(props, null, edit);
178
+ if (next) props = next;
179
+ }
180
+ return props.rPr === null ? null : docxSchema.marks.run.create({ rPr: props.rPr, format: props.format });
181
+ }
182
+ function marksFor(context) {
183
+ const marks = [];
184
+ if (context.href !== null) {
185
+ marks.push(docxSchema.marks.link.create({ href: context.href }));
186
+ }
187
+ const run = runMark(context.style);
188
+ if (run) marks.push(run);
189
+ return marks;
190
+ }
191
+ function appendText(target, source, context) {
192
+ const value = cleanText(source, context.preserveWhitespace);
193
+ if (value === "" || value === " " && target.length === 0) return;
194
+ const marks = marksFor(context);
195
+ const parts = context.preserveWhitespace ? value.split("\n") : [value];
196
+ parts.forEach((part, index) => {
197
+ if (index > 0) {
198
+ target.push(docxSchema.nodes.hardBreak.create(null, null, marks));
199
+ }
200
+ if (part !== "") target.push(docxSchema.text(part, marks));
201
+ });
202
+ }
203
+ function appendInline(target, node, context, readElement) {
204
+ if (node.nodeType === node.TEXT_NODE) {
205
+ appendText(target, node.nodeValue ?? "", context);
206
+ return;
207
+ }
208
+ if (node.nodeType !== node.ELEMENT_NODE) return;
209
+ const element = node;
210
+ if (IGNORED_TAGS.has(element.tagName)) return;
211
+ const next = contextFor(context, element);
212
+ if (readElement?.(target, element, next)) return;
213
+ if (element.classList.contains(editorClassNames.tab)) {
214
+ const marks = marksFor(next);
215
+ const tab = docxSchema.marks.tab.create();
216
+ target.push(docxSchema.text(" ", tab.addToSet(marks)));
217
+ return;
218
+ }
219
+ if (element.tagName === "BR") {
220
+ target.push(docxSchema.nodes.hardBreak.create(null, null, marksFor(next)));
221
+ return;
222
+ }
223
+ for (const child of element.childNodes) {
224
+ appendInline(target, child, next, readElement);
225
+ }
226
+ }
227
+ export {
228
+ appendInline,
229
+ contextFor,
230
+ marksFor,
231
+ withInlineStyle
232
+ };
@@ -0,0 +1,8 @@
1
+ import type { Command } from "prosemirror-state";
2
+ /** Breaks the line without splitting the paragraph */
3
+ export declare const insertLineBreak: Command;
4
+ /**
5
+ * Starts the next page: the very `w:br` the editor already reads and draws in a document that
6
+ * arrived with one.
7
+ */
8
+ export declare const insertPageBreak: Command;
@@ -0,0 +1,19 @@
1
+ // src/editor/commands/breakCommands.ts
2
+ import { docxSchema } from "../../schema/index.js";
3
+ import { replacementShut } from "../../schema/locks.js";
4
+ function insertBreak(brAttrs) {
5
+ return (state, dispatch) => {
6
+ if (replacementShut(state.selection, state.doc)) return false;
7
+ if (dispatch) {
8
+ const br = docxSchema.nodes.hardBreak.create({ brAttrs });
9
+ dispatch(state.tr.replaceSelectionWith(br).scrollIntoView());
10
+ }
11
+ return true;
12
+ };
13
+ }
14
+ var insertLineBreak = insertBreak(null);
15
+ var insertPageBreak = insertBreak('w:type="page"');
16
+ export {
17
+ insertLineBreak,
18
+ insertPageBreak
19
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Dry-runs external commands and checks every produced transaction against document locks without
3
+ * dispatching them or triggering the locked-content plugin's side effects.
4
+ */
5
+ import type { Command, EditorState } from "prosemirror-state";
6
+ export declare function canRunCommand(command: Command, state: EditorState): boolean;
@@ -0,0 +1,10 @@
1
+ // src/editor/commands/canRunCommand.ts
2
+ import { transactionAllowed } from "../../schema/locks.js";
3
+ function canRunCommand(command, state) {
4
+ const built = [];
5
+ if (!command(state, (tr) => built.push(tr))) return false;
6
+ return built.every((tr) => transactionAllowed(tr, state.doc));
7
+ }
8
+ export {
9
+ canRunCommand
10
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./comments/editing";
2
+ export * from "./comments/model";
3
+ export * from "./comments/reading";
@@ -0,0 +1,4 @@
1
+ // src/editor/commands/commentCommands.ts
2
+ export * from "./comments/editing.js";
3
+ export * from "./comments/model.js";
4
+ export * from "./comments/reading.js";
@@ -0,0 +1,21 @@
1
+ /** Edits Word comments through their range markers and reference nodes. */
2
+ import { type Command, type EditorState } from "prosemirror-state";
3
+ import type { NewComment } from "./model";
4
+ /** Whether a non-empty selection in one paragraph can receive a comment. */
5
+ export declare function canAddComment(state: EditorState): boolean;
6
+ /** Adds a plain-text comment to the current text selection. */
7
+ export declare function addComment(comment: NewComment): Command;
8
+ /** Replaces the plain-text body of one comment, retaining its author and anchor. */
9
+ export declare function updateComment(id: string, text: string): Command;
10
+ /** Marks a comment thread resolved or open without deleting it. */
11
+ export declare function setCommentResolved(id: string, resolved: boolean): Command;
12
+ /** Adds a plain-text reply and reopens the thread when it was resolved. */
13
+ export declare function addCommentReply(id: string, reply: NewComment): Command;
14
+ /** Replaces the plain-text body of one reply. */
15
+ export declare function updateCommentReply(commentId: string, replyId: string, text: string): Command;
16
+ /** Removes one reply while retaining its root comment and anchor. */
17
+ export declare function removeCommentReply(commentId: string, replyId: string): Command;
18
+ /** Removes a comment's range markers, reference and Comments-part entry. */
19
+ export declare function removeComment(id: string): Command;
20
+ /** Selects the text anchored by a comment, or places the caret at a point comment. */
21
+ export declare function selectComment(id: string): Command;