@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,36 @@
1
+ /** The wordprocessing namespace that every element we read lives in */
2
+ export declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
3
+ /**
4
+ * The relationship namespace. It is both where the `r:embed` attributes live and the base
5
+ * every relationship type name is built on
6
+ */
7
+ export declare const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
8
+ /** The name with its namespace prefix stripped off (`w:ascii` -> `ascii`) */
9
+ export declare function localPart(name: string): string;
10
+ /**
11
+ * Makes a value safe to drop verbatim into either text content or an attribute value.
12
+ *
13
+ * Attribute values are wrapped in double quotes everywhere we write them, so single quotes are left alone.
14
+ * Control characters that cannot be carried are stripped. Incoming text is already filtered by
15
+ * `editor/plainText`, but this is the last net that keeps an unopenable file from going out
16
+ * no matter which path the text came in through.
17
+ */
18
+ export declare function escapeXml(value: string): string;
19
+ export declare function decodeUtf8(bytes: Uint8Array): {
20
+ text: string;
21
+ hadBom: boolean;
22
+ };
23
+ export declare function encodeUtf8(text: string, withBom: boolean): Uint8Array;
24
+ export declare function parseXml(source: string): Document;
25
+ export declare function elementChildren(el: Element): Element[];
26
+ export declare function childByLocalName(el: Element, name: string): Element | null;
27
+ /** Turns an opening tag's attributes into an `a="b" c="d"` string */
28
+ export declare function attrString(el: Element): string | null;
29
+ /**
30
+ * Turns a single element back into an XML string.
31
+ *
32
+ * The browser's XMLSerializer adds fresh declarations such as `xmlns:w` to a fragment it cut out.
33
+ * That declaration already sits at the very top of the document, so we write the string ourselves
34
+ * to keep markup that was not in the original from creeping in.
35
+ */
36
+ export declare function serializeXml(el: Element): string;
@@ -0,0 +1,89 @@
1
+ // src/ooxml/xml.ts
2
+ import { DocxImportError } from "./errors.js";
3
+ var W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
4
+ var R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
5
+ function localPart(name) {
6
+ const colon = name.indexOf(":");
7
+ return colon === -1 ? name : name.slice(colon + 1);
8
+ }
9
+ var FORBIDDEN = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/;
10
+ var ALL_FORBIDDEN = new RegExp(FORBIDDEN, "g");
11
+ function escapeXml(value) {
12
+ const escaped = value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
13
+ return FORBIDDEN.test(escaped) ? escaped.replace(ALL_FORBIDDEN, "") : escaped;
14
+ }
15
+ function decodeUtf8(bytes) {
16
+ const hadBom = bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191;
17
+ return { text: new TextDecoder("utf-8").decode(bytes), hadBom };
18
+ }
19
+ function encodeUtf8(text, withBom) {
20
+ return new TextEncoder().encode(withBom ? "\uFEFF" + text : text);
21
+ }
22
+ function declaresDtd(source) {
23
+ const DOCTYPE = "<!DOCTYPE";
24
+ let at = 0;
25
+ for (; ; ) {
26
+ const opens = source.indexOf("<", at);
27
+ if (opens === -1) return false;
28
+ const opening = source.slice(opens, opens + DOCTYPE.length);
29
+ if (opening.toUpperCase() === DOCTYPE) return true;
30
+ const closes = opening.startsWith("<!--") ? source.indexOf("-->", opens + 4) : opening.startsWith("<?") ? source.indexOf("?>", opens + 2) : -1;
31
+ if (closes === -1) return false;
32
+ at = closes;
33
+ }
34
+ }
35
+ function parseXml(source) {
36
+ if (declaresDtd(source)) {
37
+ throw new DocxImportError("malformed-xml", "the XML declares a DTD");
38
+ }
39
+ const doc = new DOMParser().parseFromString(source, "application/xml");
40
+ if (doc.getElementsByTagName("parsererror").length > 0) {
41
+ throw new DocxImportError("malformed-xml", "could not parse the XML");
42
+ }
43
+ return doc;
44
+ }
45
+ function elementChildren(el) {
46
+ return Array.from(el.children);
47
+ }
48
+ function childByLocalName(el, name) {
49
+ return elementChildren(el).find((child) => child.localName === name) ?? null;
50
+ }
51
+ function attrString(el) {
52
+ if (el.attributes.length === 0) return null;
53
+ return Array.from(el.attributes).map((attr) => `${attr.name}="${escapeXml(attr.value)}"`).join(" ");
54
+ }
55
+ function isElement(node) {
56
+ return node.nodeType === Node.ELEMENT_NODE;
57
+ }
58
+ function serializeChildNode(node) {
59
+ if (isElement(node)) return serializeXml(node);
60
+ if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) {
61
+ return escapeXml(node.nodeValue ?? "");
62
+ }
63
+ if (node.nodeType === Node.COMMENT_NODE) {
64
+ return `<!--${node.nodeValue ?? ""}-->`;
65
+ }
66
+ throw new DocxImportError(
67
+ "unsupported-content",
68
+ "the document holds an XML node we cannot write back out"
69
+ );
70
+ }
71
+ function serializeXml(el) {
72
+ const attrs = attrString(el);
73
+ const open = attrs ? `<${el.nodeName} ${attrs}` : `<${el.nodeName}`;
74
+ const inner = Array.from(el.childNodes).map(serializeChildNode).join("");
75
+ return inner ? `${open}>${inner}</${el.nodeName}>` : `${open}/>`;
76
+ }
77
+ export {
78
+ R_NS,
79
+ W_NS,
80
+ attrString,
81
+ childByLocalName,
82
+ decodeUtf8,
83
+ elementChildren,
84
+ encodeUtf8,
85
+ escapeXml,
86
+ localPart,
87
+ parseXml,
88
+ serializeXml
89
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Draws the gaps between pages on the sheet, plus a number for each page.
3
+ *
4
+ * Straddling blocks have already been moved to the next page, so there is no text under
5
+ * these bands.
6
+ * Only the places crossed by a block taller than one page are marked over the text, with
7
+ * a faint dotted line.
8
+ * The box only paints, so the mouse still reaches the text beneath it.
9
+ */
10
+ import type { ReactElement } from "react";
11
+ import { type HeadersFooters } from "../docx/headersFooters";
12
+ import type { PageOverlay } from "./usePageLayout";
13
+ export declare function PageGuides({ overlay, headersFooters, }: {
14
+ overlay: PageOverlay;
15
+ headersFooters?: HeadersFooters;
16
+ }): ReactElement;
@@ -0,0 +1,114 @@
1
+ // src/page/PageGuides.tsx
2
+ import {
3
+ displayPageNumber,
4
+ headerFooterAlign,
5
+ headerFooterText
6
+ } from "../docx/headersFooters.js";
7
+ import { editorClassNames } from "../styles/classNames.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function badgeTitle(badge) {
10
+ return badge.exactPage ? `Page ${badge.page}` : `Page ${badge.page} (approximate)`;
11
+ }
12
+ function PageGuides({
13
+ overlay,
14
+ headersFooters
15
+ }) {
16
+ const totalPages = overlay.pages.length;
17
+ return /* @__PURE__ */ jsxs(
18
+ "div",
19
+ {
20
+ className: editorClassNames.pageGuides,
21
+ style: {
22
+ left: `${overlay.left}px`,
23
+ top: `${overlay.top}px`,
24
+ width: `${overlay.width}px`,
25
+ height: `${overlay.sheetHeight}px`
26
+ },
27
+ "aria-hidden": "true",
28
+ children: [
29
+ overlay.marks.map((mark) => /* @__PURE__ */ jsx(
30
+ "div",
31
+ {
32
+ className: mark.crossed ? editorClassNames.pageCrossed : editorClassNames.pageSplit,
33
+ style: {
34
+ top: `${mark.top}px`,
35
+ height: mark.height > 0 ? `${mark.height}px` : void 0
36
+ }
37
+ },
38
+ mark.page
39
+ )),
40
+ overlay.badges.map((badge) => /* @__PURE__ */ jsx(
41
+ "span",
42
+ {
43
+ className: editorClassNames.pageBadge,
44
+ style: { top: `${badge.top}px` },
45
+ title: badgeTitle(badge),
46
+ children: badge.page
47
+ },
48
+ badge.page
49
+ )),
50
+ headersFooters && overlay.pages.flatMap((page) => {
51
+ if (page.crossed) return [];
52
+ const number = displayPageNumber(headersFooters, page.page);
53
+ const header = headerFooterText(
54
+ headersFooters.headers,
55
+ headersFooters,
56
+ page.page,
57
+ totalPages
58
+ );
59
+ const footer = headerFooterText(
60
+ headersFooters.footers,
61
+ headersFooters,
62
+ page.page,
63
+ totalPages
64
+ );
65
+ const headerAlign = headerFooterAlign(
66
+ headersFooters.headers,
67
+ headersFooters,
68
+ page.page
69
+ );
70
+ const footerAlign = headerFooterAlign(
71
+ headersFooters.footers,
72
+ headersFooters,
73
+ page.page
74
+ );
75
+ return [
76
+ header === null ? null : /* @__PURE__ */ jsx(
77
+ "div",
78
+ {
79
+ className: editorClassNames.pageHeader,
80
+ style: {
81
+ top: `${page.headerTop}px`,
82
+ left: `${page.left}px`,
83
+ width: `${page.width}px`,
84
+ textAlign: headerAlign ?? void 0
85
+ },
86
+ title: `Page ${number} header`,
87
+ children: header
88
+ },
89
+ `header-${page.page}`
90
+ ),
91
+ footer === null ? null : /* @__PURE__ */ jsx(
92
+ "div",
93
+ {
94
+ className: editorClassNames.pageFooter,
95
+ style: {
96
+ top: `${page.footerTop}px`,
97
+ left: `${page.left}px`,
98
+ width: `${page.width}px`,
99
+ textAlign: footerAlign ?? void 0
100
+ },
101
+ title: `Page ${number} footer`,
102
+ children: footer
103
+ },
104
+ `footer-${page.page}`
105
+ )
106
+ ];
107
+ })
108
+ ]
109
+ }
110
+ );
111
+ }
112
+ export {
113
+ PageGuides
114
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Measures the sheet as drawn on screen: the height of each body block, the gap above it, and
3
+ * where the page breaks inside it stand, with nothing computed line by line.
4
+ *
5
+ * The engine's own marks are taken back off as they are read, so a block already pushed and a
6
+ * break already given its space read as they would with neither applied. A measurement that read
7
+ * them in would add to what is already there, and the layout would creep on every pass.
8
+ * Where there is no layout (in tests) everything is 0, so the result is a single page.
9
+ */
10
+ import type { EditorView } from "prosemirror-view";
11
+ import type { MeasuredBlock } from "./pageLayout";
12
+ /**
13
+ * The measurements taken in order to draw the page overlay. Positions are relative to
14
+ * the overlay box
15
+ */
16
+ export interface SheetMeasure {
17
+ left: number;
18
+ top: number;
19
+ width: number;
20
+ /** The sheet's top and bottom padding */
21
+ contentTop: number;
22
+ contentBottom: number;
23
+ blocks: MeasuredBlock[];
24
+ }
25
+ export declare function measureSheet(view: EditorView, layer: HTMLElement): SheetMeasure;
@@ -0,0 +1,80 @@
1
+ // src/page/measureBlocks.ts
2
+ import { editorAttributes } from "../styles/classNames.js";
3
+ import { measureTable } from "./tableMeasurements.js";
4
+ var PAGE_BREAK_BR = `br[${editorAttributes.breakType}="page"]`;
5
+ var BREAK_SPACE = `[${editorAttributes.pageBreakSpace}]`;
6
+ function pixels(value) {
7
+ const parsed = Number.parseFloat(value);
8
+ return Number.isFinite(parsed) ? parsed : 0;
9
+ }
10
+ function visualScale(element) {
11
+ const scale = pixels(getComputedStyle(element).zoom);
12
+ return scale > 0 ? scale : 1;
13
+ }
14
+ function appliedPush(element) {
15
+ return pixels(element.getAttribute(editorAttributes.pagePush) ?? "");
16
+ }
17
+ function drawnBlocks(view) {
18
+ const found = [];
19
+ view.state.doc.forEach((_node, offset) => {
20
+ const dom = view.nodeDOM(offset);
21
+ if (dom instanceof HTMLElement && dom.getBoundingClientRect().height > 0) {
22
+ found.push({ pos: offset, dom });
23
+ }
24
+ });
25
+ return found;
26
+ }
27
+ function breakWithoutSpace(dom, spaces) {
28
+ return dom.querySelectorAll(PAGE_BREAK_BR).length > spaces;
29
+ }
30
+ function measureSheet(view, layer) {
31
+ const sheet = view.dom;
32
+ const sheetRect = sheet.getBoundingClientRect();
33
+ const layerRect = layer.getBoundingClientRect();
34
+ const style = getComputedStyle(sheet);
35
+ const scale = visualScale(layer);
36
+ const contentTop = pixels(style.paddingTop);
37
+ const contentBottom = pixels(style.paddingBottom);
38
+ const sheetY = (viewportY) => (viewportY - sheetRect.top) / scale;
39
+ const blocks = [];
40
+ let previousBottom = contentTop;
41
+ let applied = 0;
42
+ let breakAfterPrevious = false;
43
+ for (const { pos, dom } of drawnBlocks(view)) {
44
+ const node = view.state.doc.nodeAt(pos);
45
+ const rect = dom.getBoundingClientRect();
46
+ applied += appliedPush(dom);
47
+ const top = sheetY(rect.top) - applied;
48
+ const measuredTable = node ? measureTable(view, node, pos, dom, scale) : null;
49
+ const breaks = [];
50
+ const spaces = Array.from(dom.querySelectorAll(BREAK_SPACE));
51
+ for (const space of spaces) {
52
+ const box = space.getBoundingClientRect();
53
+ breaks.push(sheetY(box.top) - applied - top);
54
+ applied += box.height / scale;
55
+ }
56
+ applied += measuredTable?.appliedHeight ?? 0;
57
+ const bottom = sheetY(rect.bottom) - applied;
58
+ blocks.push({
59
+ pos,
60
+ gap: top - previousBottom,
61
+ height: bottom - top,
62
+ breakBefore: breakAfterPrevious || dom.hasAttribute(editorAttributes.pageBreakBefore),
63
+ breaks,
64
+ ...measuredTable ? { table: measuredTable.table } : {}
65
+ });
66
+ previousBottom = bottom;
67
+ breakAfterPrevious = breakWithoutSpace(dom, spaces.length);
68
+ }
69
+ return {
70
+ left: (sheetRect.left - layerRect.left) / scale,
71
+ top: (sheetRect.top - layerRect.top) / scale,
72
+ width: sheetRect.width / scale,
73
+ contentTop,
74
+ contentBottom,
75
+ blocks
76
+ };
77
+ }
78
+ export {
79
+ measureSheet
80
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Decorations that move content to the next page: block pushes, page-break spaces, and table
3
+ * continuation rows.
4
+ *
5
+ * The document model is left untouched, so no trace of them is left in
6
+ * the exported XML or in the edit history.
7
+ */
8
+ import { Plugin } from "prosemirror-state";
9
+ import { DecorationSet, type EditorView } from "prosemirror-view";
10
+ import type { BlockPush, BreakSpace, TableContinuation } from "./pageLayout";
11
+ /**
12
+ * One break's space while the document changes under it.
13
+ *
14
+ * The layout counts breaks inside the block it measured (`page/pageLayout`), and an edit anywhere
15
+ * before a break shifts that count, so what is kept here is the position of the `br` the space
16
+ * belongs to: a position maps through an edit, an ordinal does not.
17
+ */
18
+ interface SpaceMark {
19
+ /** Where the `br` this space is put on stands */
20
+ at: number;
21
+ height: number;
22
+ }
23
+ interface PageMarks {
24
+ pushes: readonly BlockPush[];
25
+ spaces: readonly SpaceMark[];
26
+ tableContinuations: readonly TableContinuation[];
27
+ decorations: DecorationSet;
28
+ }
29
+ export declare function pageDecorations(): Plugin<PageMarks>;
30
+ /** Does nothing when the same values are already applied */
31
+ export declare function setPagePushes(view: EditorView, pushes: readonly BlockPush[]): void;
32
+ /** Does nothing when the same values are already applied */
33
+ export declare function setPageBreakSpaces(view: EditorView, spaces: readonly BreakSpace[]): void;
34
+ /** Does nothing when the same table continuations are already applied */
35
+ export declare function setTableContinuations(view: EditorView, continuations: readonly TableContinuation[]): void;
36
+ export {};
@@ -0,0 +1,211 @@
1
+ // src/page/pageDecorations.ts
2
+ import { Plugin, PluginKey } from "prosemirror-state";
3
+ import { Decoration, DecorationSet } from "prosemirror-view";
4
+ import { docxSchema, isPageBreak } from "../schema/index.js";
5
+ import { editorAttributes } from "../styles/classNames.js";
6
+ var marksKey = new PluginKey("docxPageDecorations");
7
+ function pushStyle(marginTop) {
8
+ return `margin-block-start:${marginTop}px`;
9
+ }
10
+ function spaceStyle(height) {
11
+ return `display:block;height:${height}px`;
12
+ }
13
+ function isPageBreakNode(node) {
14
+ return node?.type === docxSchema.nodes.hardBreak && isPageBreak(node.attrs.brAttrs);
15
+ }
16
+ function pageBreaksIn(block, blockPos) {
17
+ const found = [];
18
+ if (block.type !== docxSchema.nodes.paragraph) return found;
19
+ block.forEach((child, offset) => {
20
+ if (isPageBreakNode(child)) {
21
+ found.push({ at: blockPos + 1 + offset, size: child.nodeSize });
22
+ }
23
+ });
24
+ return found;
25
+ }
26
+ function breakSpaces(block, blockPos, heights, into) {
27
+ for (const { at, size } of pageBreaksIn(block, blockPos)) {
28
+ const height = heights.get(at) ?? 0;
29
+ into.push(
30
+ Decoration.inline(at, at + size, {
31
+ nodeName: "span",
32
+ style: spaceStyle(height),
33
+ [editorAttributes.pageBreakSpace]: `${height}`
34
+ })
35
+ );
36
+ }
37
+ }
38
+ function spaceMarks(doc, spaces) {
39
+ return spaces.flatMap((space) => {
40
+ const block = doc.nodeAt(space.pos);
41
+ const found = block ? pageBreaksIn(block, space.pos)[space.index] : null;
42
+ return found ? [{ at: found.at, height: space.height }] : [];
43
+ });
44
+ }
45
+ function tableSpace(continuation) {
46
+ const row = document.createElement("tr");
47
+ row.setAttribute(editorAttributes.tablePageSpace, `${continuation.height}`);
48
+ row.setAttribute("aria-hidden", "true");
49
+ row.setAttribute("contenteditable", "false");
50
+ row.style.height = `${continuation.height}px`;
51
+ const cell = document.createElement("td");
52
+ cell.colSpan = continuation.columns;
53
+ cell.style.height = `${continuation.height}px`;
54
+ row.append(cell);
55
+ return row;
56
+ }
57
+ function repeatedHeader(view, rowPos) {
58
+ const source = view.nodeDOM(rowPos);
59
+ const row = source instanceof HTMLElement && source.tagName === "TR" ? source.cloneNode(true) : document.createElement("tr");
60
+ row.setAttribute(editorAttributes.tableRepeatedHeader, "");
61
+ row.setAttribute("aria-hidden", "true");
62
+ row.setAttribute("contenteditable", "false");
63
+ row.removeAttribute("id");
64
+ row.querySelectorAll("[id]").forEach((element) => {
65
+ element.removeAttribute("id");
66
+ });
67
+ return row;
68
+ }
69
+ function tableContinuationDecorations(continuations, into) {
70
+ continuations.forEach((continuation) => {
71
+ into.push(
72
+ Decoration.widget(continuation.pos, () => tableSpace(continuation), {
73
+ key: `table-page-space-${continuation.pos}-${continuation.height}-${continuation.columns}`,
74
+ side: -100
75
+ })
76
+ );
77
+ continuation.headerRows.forEach((rowPos, headerIndex) => {
78
+ into.push(
79
+ Decoration.widget(
80
+ continuation.pos,
81
+ (view) => repeatedHeader(view, rowPos),
82
+ {
83
+ key: `table-repeated-header-${continuation.pos}-${headerIndex}-` + continuation.headerSignature,
84
+ side: -90 + headerIndex
85
+ }
86
+ )
87
+ );
88
+ });
89
+ });
90
+ }
91
+ function decorationsFor(doc, pushes, spaces, tableContinuations) {
92
+ const byPos = new Map(pushes.map((push) => [push.pos, push]));
93
+ const heights = new Map(spaces.map((space) => [space.at, space.height]));
94
+ const decorations = [];
95
+ doc.forEach((node, offset) => {
96
+ const push = byPos.get(offset);
97
+ if (push) {
98
+ decorations.push(
99
+ Decoration.node(offset, offset + node.nodeSize, {
100
+ style: pushStyle(push.marginTop),
101
+ [editorAttributes.pagePush]: `${push.push}`
102
+ })
103
+ );
104
+ }
105
+ breakSpaces(node, offset, heights, decorations);
106
+ });
107
+ tableContinuationDecorations(tableContinuations, decorations);
108
+ return DecorationSet.create(doc, decorations);
109
+ }
110
+ function marksFor(doc, pushes, spaces, tableContinuations) {
111
+ return {
112
+ pushes,
113
+ spaces,
114
+ tableContinuations,
115
+ decorations: decorationsFor(doc, pushes, spaces, tableContinuations)
116
+ };
117
+ }
118
+ function samePushes(a, b) {
119
+ return a.length === b.length && a.every((push, index) => {
120
+ const other = b[index];
121
+ return other !== void 0 && other.pos === push.pos && other.marginTop === push.marginTop;
122
+ });
123
+ }
124
+ function sameSpaces(a, b) {
125
+ return a.length === b.length && a.every((space, index) => {
126
+ const other = b[index];
127
+ return other !== void 0 && other.at === space.at && other.height === space.height;
128
+ });
129
+ }
130
+ function sameTableContinuations(a, b) {
131
+ return a.length === b.length && a.every((continuation, index) => {
132
+ const other = b[index];
133
+ return other !== void 0 && other.pos === continuation.pos && other.height === continuation.height && other.columns === continuation.columns && other.headerSignature === continuation.headerSignature && other.headerRows.length === continuation.headerRows.length && other.headerRows.every(
134
+ (rowPos, rowIndex) => rowPos === continuation.headerRows[rowIndex]
135
+ );
136
+ });
137
+ }
138
+ function pageDecorations() {
139
+ return new Plugin({
140
+ key: marksKey,
141
+ state: {
142
+ init: (_config, state) => marksFor(state.doc, [], [], []),
143
+ apply(tr, value) {
144
+ const next = tr.getMeta(marksKey);
145
+ if (next) return next;
146
+ if (!tr.docChanged) return value;
147
+ return marksFor(
148
+ tr.doc,
149
+ value.pushes.map((push) => ({
150
+ ...push,
151
+ pos: tr.mapping.map(push.pos)
152
+ })),
153
+ value.spaces.flatMap((space) => {
154
+ const at = tr.mapping.map(space.at);
155
+ return isPageBreakNode(tr.doc.nodeAt(at)) ? [{ ...space, at }] : [];
156
+ }),
157
+ value.tableContinuations.flatMap((continuation) => {
158
+ const pos = tr.mapping.map(continuation.pos);
159
+ if (tr.doc.nodeAt(pos)?.type.spec.tableRole !== "row") return [];
160
+ const headerRows = continuation.headerRows.map((rowPos) => tr.mapping.map(rowPos)).filter(
161
+ (rowPos) => tr.doc.nodeAt(rowPos)?.type.spec.tableRole === "row"
162
+ );
163
+ return [{ ...continuation, pos, headerRows }];
164
+ })
165
+ );
166
+ }
167
+ },
168
+ props: {
169
+ decorations: (state) => marksKey.getState(state)?.decorations
170
+ }
171
+ });
172
+ }
173
+ function current(view) {
174
+ return marksKey.getState(view.state) ?? marksFor(view.state.doc, [], [], []);
175
+ }
176
+ function dispatch(view, next) {
177
+ view.dispatch(
178
+ view.state.tr.setMeta(marksKey, next).setMeta("addToHistory", false)
179
+ );
180
+ }
181
+ function setPagePushes(view, pushes) {
182
+ const marks = current(view);
183
+ if (samePushes(marks.pushes, pushes)) return;
184
+ dispatch(
185
+ view,
186
+ marksFor(view.state.doc, pushes, marks.spaces, marks.tableContinuations)
187
+ );
188
+ }
189
+ function setPageBreakSpaces(view, spaces) {
190
+ const marks = current(view);
191
+ const next = spaceMarks(view.state.doc, spaces);
192
+ if (sameSpaces(marks.spaces, next)) return;
193
+ dispatch(
194
+ view,
195
+ marksFor(view.state.doc, marks.pushes, next, marks.tableContinuations)
196
+ );
197
+ }
198
+ function setTableContinuations(view, continuations) {
199
+ const marks = current(view);
200
+ if (sameTableContinuations(marks.tableContinuations, continuations)) return;
201
+ dispatch(
202
+ view,
203
+ marksFor(view.state.doc, marks.pushes, marks.spaces, continuations)
204
+ );
205
+ }
206
+ export {
207
+ pageDecorations,
208
+ setPageBreakSpaces,
209
+ setPagePushes,
210
+ setTableContinuations
211
+ };