@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,275 @@
1
+ // src/docx/importTable.ts
2
+ import {
3
+ toCellMargins,
4
+ toInsideBorders
5
+ } from "../model/format.js";
6
+ import { childValue, wAttr } from "../ooxml/units.js";
7
+ import {
8
+ attrString,
9
+ childByLocalName,
10
+ elementChildren,
11
+ serializeXml
12
+ } from "../ooxml/xml.js";
13
+ import { docxSchema } from "../schema/index.js";
14
+ import {
15
+ layerTableFormat,
16
+ NO_STYLES
17
+ } from "./formatting.js";
18
+ import {
19
+ buildParagraph,
20
+ NO_IMPORT_SOURCES
21
+ } from "./importParagraph.js";
22
+ import { readSdtWrapper } from "./sdt.js";
23
+ import {
24
+ cellBorderDefaults,
25
+ gridEdgesOf,
26
+ layerCellMargins,
27
+ layerInsideBorders,
28
+ NO_CELL_MARGINS,
29
+ NO_INSIDE_BORDERS,
30
+ readCellFormat,
31
+ readCellMarginsOf,
32
+ readGridCols,
33
+ readInsideBorders,
34
+ readRowFormat,
35
+ readTableFormat,
36
+ readTableWidth,
37
+ tblStyleIdOf
38
+ } from "./tableFormatting.js";
39
+ function readGridSpan(tcPr) {
40
+ const value = tcPr ? childValue(tcPr, "gridSpan") : null;
41
+ const parsed = value === null ? null : Number.parseInt(value, 10);
42
+ return parsed !== null && Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
43
+ }
44
+ function readVerticalMerge(tcPr) {
45
+ const vMerge = tcPr ? childByLocalName(tcPr, "vMerge") : null;
46
+ if (!vMerge) return null;
47
+ return wAttr(vMerge, "val") === "restart" ? "restart" : "continue";
48
+ }
49
+ function readSdtCell(el) {
50
+ const wrapper = readSdtWrapper(el);
51
+ if (!wrapper) return null;
52
+ const inner = elementChildren(wrapper.content);
53
+ const tc = inner[0];
54
+ if (inner.length !== 1 || tc.localName !== "tc") return null;
55
+ if (readVerticalMerge(childByLocalName(tc, "tcPr")) === "continue") {
56
+ return null;
57
+ }
58
+ return {
59
+ el: tc,
60
+ control: {
61
+ prefix: wrapper.prefix,
62
+ contentsLocked: wrapper.contentsLocked,
63
+ deletionLocked: wrapper.deletionLocked
64
+ }
65
+ };
66
+ }
67
+ function readRow(el) {
68
+ const cells = [];
69
+ let tblPrEx = null;
70
+ for (const child of elementChildren(el)) {
71
+ if (child.localName === "trPr") continue;
72
+ if (child.localName === "tblPrEx") {
73
+ tblPrEx = child;
74
+ continue;
75
+ }
76
+ const sdt = child.localName === "sdt" ? readSdtCell(child) : null;
77
+ if (!sdt && child.localName !== "tc") return null;
78
+ const tc = sdt ? sdt.el : child;
79
+ const tcPr = childByLocalName(tc, "tcPr");
80
+ cells.push({
81
+ el: tc,
82
+ gridSpan: readGridSpan(tcPr),
83
+ vMerge: readVerticalMerge(tcPr),
84
+ control: sdt ? sdt.control : null
85
+ });
86
+ }
87
+ return cells.length > 0 ? { el, tblPrEx, cells } : null;
88
+ }
89
+ function readTableParts(el) {
90
+ let tblPr = null;
91
+ let tblGrid = null;
92
+ const rows = [];
93
+ for (const child of elementChildren(el)) {
94
+ if (child.localName === "tblPr") {
95
+ tblPr = child;
96
+ continue;
97
+ }
98
+ if (child.localName === "tblGrid") {
99
+ tblGrid = child;
100
+ continue;
101
+ }
102
+ if (child.localName !== "tr") return null;
103
+ const row = readRow(child);
104
+ if (!row) return null;
105
+ rows.push(row);
106
+ }
107
+ return rows.length > 0 ? { tblPr, tblGrid, rows } : null;
108
+ }
109
+ function resolveVerticalMerges(rows, width) {
110
+ const drafts = [];
111
+ let open = /* @__PURE__ */ new Map();
112
+ for (const [index, row] of rows.entries()) {
113
+ const rowDrafts = [];
114
+ const next = /* @__PURE__ */ new Map();
115
+ let col = 0;
116
+ for (const cell of row.cells) {
117
+ if (cell.vMerge === "continue") {
118
+ const chain = open.get(col);
119
+ if (!chain || chain.colspan !== cell.gridSpan) return null;
120
+ chain.rowspan += 1;
121
+ next.set(col, chain);
122
+ } else {
123
+ const draft = {
124
+ el: cell.el,
125
+ row: index,
126
+ col,
127
+ colspan: cell.gridSpan,
128
+ rowspan: 1,
129
+ control: cell.control
130
+ };
131
+ rowDrafts.push(draft);
132
+ if (cell.vMerge === "restart") next.set(col, draft);
133
+ }
134
+ col += cell.gridSpan;
135
+ }
136
+ if (col !== width) return null;
137
+ if (rowDrafts.length === 0) return null;
138
+ drafts.push(rowDrafts);
139
+ open = next;
140
+ }
141
+ return drafts;
142
+ }
143
+ function gridWidthOf(rows) {
144
+ const widths = rows.map(
145
+ (row) => row.cells.reduce((sum, cell) => sum + cell.gridSpan, 0)
146
+ );
147
+ const first = widths[0];
148
+ return widths.every((width) => width === first) ? first : null;
149
+ }
150
+ function buildCellBlock(el, sources) {
151
+ if (el.localName === "p") {
152
+ const paragraph = buildParagraph(el, null, sources);
153
+ if (paragraph) return paragraph;
154
+ }
155
+ return docxSchema.nodes.rawBlock.create({
156
+ xml: serializeXml(el),
157
+ name: el.nodeName
158
+ });
159
+ }
160
+ function cellBorderDefaultsFor(draft, lines) {
161
+ return cellBorderDefaults(
162
+ gridEdgesOf(
163
+ {
164
+ top: draft.row,
165
+ bottom: draft.row + draft.rowspan,
166
+ left: draft.col,
167
+ right: draft.col + draft.colspan
168
+ },
169
+ lines
170
+ ),
171
+ lines.outer,
172
+ lines.inside
173
+ );
174
+ }
175
+ function buildCell(draft, lines, sources) {
176
+ const tcPr = childByLocalName(draft.el, "tcPr");
177
+ const blocks = [];
178
+ for (const child of elementChildren(draft.el)) {
179
+ if (child.localName === "tcPr") continue;
180
+ blocks.push(buildCellBlock(child, sources));
181
+ }
182
+ if (blocks.length === 0) return null;
183
+ return docxSchema.nodes.tableCell.create(
184
+ {
185
+ colspan: draft.colspan,
186
+ rowspan: draft.rowspan,
187
+ colwidth: null,
188
+ tcAttrs: attrString(draft.el),
189
+ tcPr: tcPr ? serializeXml(tcPr) : null,
190
+ tcW: readTableWidth(tcPr, "tcW"),
191
+ format: readCellFormat(
192
+ tcPr,
193
+ cellBorderDefaultsFor(draft, lines),
194
+ lines.margins
195
+ ),
196
+ sdtPrefix: draft.control?.prefix ?? null,
197
+ sdtContentsLocked: draft.control?.contentsLocked ?? false,
198
+ sdtDeletionLocked: draft.control?.deletionLocked ?? false
199
+ },
200
+ blocks
201
+ );
202
+ }
203
+ function buildRow(row, drafts, lines, sources) {
204
+ const cells = [];
205
+ for (const draft of drafts) {
206
+ const cell = buildCell(draft, lines, sources);
207
+ if (!cell) return null;
208
+ cells.push(cell);
209
+ }
210
+ const trPr = childByLocalName(row.el, "trPr");
211
+ return docxSchema.nodes.tableRow.create(
212
+ {
213
+ trAttrs: attrString(row.el),
214
+ tblPrEx: row.tblPrEx ? serializeXml(row.tblPrEx) : null,
215
+ trPr: trPr ? serializeXml(trPr) : null,
216
+ format: readRowFormat(trPr)
217
+ },
218
+ cells
219
+ );
220
+ }
221
+ function tableStyleOf(tblPr, styles, defaultTableStyleId) {
222
+ const styleId = tblStyleIdOf(tblPr);
223
+ return (styleId !== null ? styles.get(styleId) : void 0) ?? (defaultTableStyleId !== null ? styles.get(defaultTableStyleId) : void 0);
224
+ }
225
+ function buildTable(el, srcId, sources = NO_IMPORT_SOURCES, styles = NO_STYLES, defaultTableStyleId = null) {
226
+ const parts = readTableParts(el);
227
+ if (!parts) return null;
228
+ const gridCols = readGridCols(parts.tblGrid);
229
+ const width = gridWidthOf(parts.rows);
230
+ if (width === null || width === 0) return null;
231
+ if (gridCols.length > 0 && gridCols.length !== width) return null;
232
+ const drafts = resolveVerticalMerges(parts.rows, width);
233
+ if (!drafts) return null;
234
+ const style = tableStyleOf(parts.tblPr, styles, defaultTableStyleId);
235
+ const tableFormat = layerTableFormat(
236
+ style?.table ?? {},
237
+ readTableFormat(parts.tblPr)
238
+ );
239
+ const lines = {
240
+ rows: parts.rows.length,
241
+ cols: width,
242
+ outer: tableFormat,
243
+ inside: layerInsideBorders(
244
+ style?.tableInside ?? NO_INSIDE_BORDERS,
245
+ readInsideBorders(parts.tblPr)
246
+ ),
247
+ margins: layerCellMargins(
248
+ style?.tableCellMargins ?? NO_CELL_MARGINS,
249
+ readCellMarginsOf(parts.tblPr, "tblCellMar")
250
+ )
251
+ };
252
+ const rows = [];
253
+ for (const [index, row] of parts.rows.entries()) {
254
+ const built = buildRow(row, drafts[index], lines, sources);
255
+ if (!built) return null;
256
+ rows.push(built);
257
+ }
258
+ return docxSchema.nodes.table.create(
259
+ {
260
+ srcId,
261
+ tblAttrs: attrString(el),
262
+ tblPr: parts.tblPr ? serializeXml(parts.tblPr) : null,
263
+ tblW: readTableWidth(parts.tblPr, "tblW"),
264
+ gridCols,
265
+ format: tableFormat,
266
+ // The cells need these again whenever an edit derives their display values afresh
267
+ styleInside: toInsideBorders(style?.tableInside),
268
+ styleCellMargins: toCellMargins(style?.tableCellMargins)
269
+ },
270
+ rows
271
+ );
272
+ }
273
+ export {
274
+ buildTable
275
+ };
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Reads and writes package image parts. Nodes keep data URLs so undoable document states own their
3
+ * bytes without blob-URL lifetime management; `MAX_IMAGE_BYTES` bounds the memory tradeoff.
4
+ */
5
+ import type { Node as PMNode } from "prosemirror-model";
6
+ import { type RelationshipWriter } from "./relationships";
7
+ import type { SessionStore } from "./session";
8
+ /** The images the body can refer to, as data URLs keyed by relationship id */
9
+ export type ImageSources = ReadonlyMap<string, string>;
10
+ export declare const NO_IMAGES: ImageSources;
11
+ /**
12
+ * The most one image may weigh before it is left undrawn.
13
+ *
14
+ * The document state holds every image as base64 for as long as the editor is open, and
15
+ * base64 costs a third more than the bytes, so an untrusted document would otherwise
16
+ * decide by itself how much memory the session takes. An image past the cap takes the same
17
+ * road as one no browser can draw rather than the document being refused: nothing is lost,
18
+ * since the drawing and its media part still ride back out untouched.
19
+ * No photograph a contract carries comes near this.
20
+ */
21
+ export declare const MAX_IMAGE_BYTES: number;
22
+ /**
23
+ * Every image the body part has a relationship to.
24
+ *
25
+ * A relationship we cannot follow (a linked file, a missing part, a kind no browser
26
+ * draws, an image past `MAX_IMAGE_BYTES`) is simply left out, and the drawing that points
27
+ * at it stays on the preservation path.
28
+ */
29
+ export declare function readImageSources(parts: Map<string, Uint8Array>, mainPartPath: string): ImageSources;
30
+ /**
31
+ * What the body needs to know while it is being written out: which relationship each
32
+ * inserted image ended up on, and a drawing id no other drawing in the document holds.
33
+ *
34
+ * The ids are handed out one at a time rather than planned per image, because the same
35
+ * image inserted twice shares one media part but is still two drawings, and Word expects
36
+ * every drawing in a document to have an id of its own.
37
+ */
38
+ export interface ImageRefs {
39
+ relIdOf(src: string): string | undefined;
40
+ takeDocPrId(): number;
41
+ }
42
+ /** What a serializer called on its own, outside an export, has to work with */
43
+ export declare const NO_IMAGE_REFS: ImageRefs;
44
+ export interface MediaAdditions {
45
+ refs: ImageRefs;
46
+ /** The parts to write into the zip alongside the body */
47
+ parts: ReadonlyMap<string, Uint8Array>;
48
+ }
49
+ /**
50
+ * What the package needs for the images that were inserted during editing: the media parts,
51
+ * the relationships pointing at them, and the content types declaring them.
52
+ * null when every image in the document came out of the document itself.
53
+ *
54
+ * The relationships go through the writer the export shares between its writers
55
+ * (`docx/relationships`), so the part is written once with everything in it.
56
+ *
57
+ * Bytes that are already in the package are not written a second time: an inserted image
58
+ * whose fingerprint matches one that is already there reuses its relationship.
59
+ */
60
+ export declare function planImageMedia(doc: PMNode, session: SessionStore, relationships: RelationshipWriter): MediaAdditions | null;
@@ -0,0 +1,213 @@
1
+ // src/docx/media.ts
2
+ import { DocxExportError } from "../ooxml/errors.js";
3
+ import {
4
+ imageBase64Of,
5
+ imageMimeOf,
6
+ toImageSrc
7
+ } from "../ooxml/image.js";
8
+ import { decodeUtf8, encodeUtf8, R_NS } from "../ooxml/xml.js";
9
+ import {
10
+ directoryOf,
11
+ readRelationships,
12
+ relsPathOf,
13
+ resolveTarget
14
+ } from "./relationships.js";
15
+ var IMAGE_REL_TYPE = `${R_NS}/image`;
16
+ var CONTENT_TYPES_PATH = "[Content_Types].xml";
17
+ var EXTENSION_BY_MIME = {
18
+ "image/png": "png",
19
+ "image/jpeg": "jpeg",
20
+ "image/gif": "gif",
21
+ "image/bmp": "bmp"
22
+ };
23
+ var MIME_BY_EXTENSION = /* @__PURE__ */ new Map([
24
+ ["png", "image/png"],
25
+ ["jpeg", "image/jpeg"],
26
+ ["jpg", "image/jpeg"],
27
+ ["jpe", "image/jpeg"],
28
+ ["gif", "image/gif"],
29
+ ["bmp", "image/bmp"]
30
+ ]);
31
+ function toBase64(bytes) {
32
+ const CHUNK = 32768;
33
+ let binary = "";
34
+ for (let at = 0; at < bytes.length; at += CHUNK) {
35
+ binary += String.fromCharCode(...bytes.subarray(at, at + CHUNK));
36
+ }
37
+ return btoa(binary);
38
+ }
39
+ function fromBase64(base64) {
40
+ const binary = atob(base64);
41
+ const bytes = new Uint8Array(binary.length);
42
+ for (let at = 0; at < binary.length; at += 1) {
43
+ bytes[at] = binary.charCodeAt(at);
44
+ }
45
+ return bytes;
46
+ }
47
+ function dataUrl(bytes, mime) {
48
+ return `data:${mime};base64,${toBase64(bytes)}`;
49
+ }
50
+ function mimeOfPath(path) {
51
+ const dot = path.lastIndexOf(".");
52
+ return dot === -1 ? void 0 : MIME_BY_EXTENSION.get(path.slice(dot + 1).toLowerCase());
53
+ }
54
+ var NO_IMAGES = /* @__PURE__ */ new Map();
55
+ var MAX_IMAGE_BYTES = 16 * 1024 * 1024;
56
+ function readImageSources(parts, mainPartPath) {
57
+ const sources = /* @__PURE__ */ new Map();
58
+ for (const rel of readRelationships(parts, relsPathOf(mainPartPath))) {
59
+ if (rel.type !== IMAGE_REL_TYPE || rel.external) continue;
60
+ const mime = mimeOfPath(rel.target);
61
+ const bytes = parts.get(resolveTarget(mainPartPath, rel.target));
62
+ if (!mime || !bytes || bytes.length > MAX_IMAGE_BYTES) continue;
63
+ sources.set(rel.id, dataUrl(bytes, mime));
64
+ }
65
+ return sources;
66
+ }
67
+ function contentKey(bytes) {
68
+ let a = 2166136261;
69
+ let b = 3266489909;
70
+ for (const byte of bytes) {
71
+ a = Math.imul(a ^ byte, 16777619) >>> 0;
72
+ b = Math.imul(b ^ byte, 2246822507) >>> 0;
73
+ }
74
+ const hex = (value) => value.toString(16).padStart(8, "0");
75
+ return `${bytes.length.toString(36)}${hex(a)}${hex(b)}`;
76
+ }
77
+ function imageRefs(relIdBySrc, firstDocPrId) {
78
+ let nextDocPrId = firstDocPrId;
79
+ return {
80
+ relIdOf: (src) => relIdBySrc.get(src),
81
+ takeDocPrId: () => {
82
+ const id = nextDocPrId;
83
+ nextDocPrId += 1;
84
+ return id;
85
+ }
86
+ };
87
+ }
88
+ var NO_IMAGE_REFS = {
89
+ relIdOf: () => void 0,
90
+ // Never reached: an image with no relationship to point at is refused before it is drawn
91
+ takeDocPrId: () => 1
92
+ };
93
+ function insertedImageSrcs(doc) {
94
+ const srcs = [];
95
+ doc.descendants((node) => {
96
+ if (node.type.name !== "image" || typeof node.attrs.xml === "string") {
97
+ return true;
98
+ }
99
+ const src = toImageSrc(node.attrs.src);
100
+ if (src !== null && !srcs.includes(src)) srcs.push(src);
101
+ return true;
102
+ });
103
+ return srcs;
104
+ }
105
+ function decodeImage(src) {
106
+ const mime = imageMimeOf(src);
107
+ if (mime === null) {
108
+ throw new DocxExportError(
109
+ "unsupported-content",
110
+ "an inserted image is of a kind we cannot write"
111
+ );
112
+ }
113
+ try {
114
+ const bytes = fromBase64(imageBase64Of(src));
115
+ return {
116
+ bytes,
117
+ extension: EXTENSION_BY_MIME[mime],
118
+ key: contentKey(bytes)
119
+ };
120
+ } catch (error) {
121
+ throw new DocxExportError(
122
+ "unsupported-content",
123
+ "an inserted image's bytes could not be decoded",
124
+ { cause: error }
125
+ );
126
+ }
127
+ }
128
+ function imageRelIdsByContent(session, rels) {
129
+ const byContent = /* @__PURE__ */ new Map();
130
+ for (const rel of rels) {
131
+ if (rel.type !== IMAGE_REL_TYPE || rel.external) continue;
132
+ const bytes = session.parts.get(
133
+ resolveTarget(session.mainPartPath, rel.target)
134
+ );
135
+ if (!bytes) continue;
136
+ const key = contentKey(bytes);
137
+ if (!byContent.has(key)) byContent.set(key, rel.id);
138
+ }
139
+ return byContent;
140
+ }
141
+ var DOC_PR_ID = /<(?:[\w.-]+:)?docPr\b[^>]*\bid="(\d+)"/g;
142
+ function maxDocPrId(session) {
143
+ let max = 0;
144
+ for (const block of session.blocks) {
145
+ for (const match of block.xml.matchAll(DOC_PR_ID)) {
146
+ max = Math.max(max, Number.parseInt(match[1], 10));
147
+ }
148
+ }
149
+ return max;
150
+ }
151
+ var TYPES_OPEN_TAG = /<(?:[\w.-]+:)?Types\b[^>]*>/;
152
+ function withImageContentTypes(parts, extensions) {
153
+ const original = parts.get(CONTENT_TYPES_PATH);
154
+ if (!original) {
155
+ throw new DocxExportError(
156
+ "missing-content-types",
157
+ `cannot add an image to a package that has no ${CONTENT_TYPES_PATH}`
158
+ );
159
+ }
160
+ const { text, hadBom } = decodeUtf8(original);
161
+ const missing = Array.from(extensions).filter(
162
+ (extension) => !new RegExp(`<Default[^>]+Extension="${extension}"`, "i").test(text)
163
+ );
164
+ if (missing.length === 0) return null;
165
+ const open = TYPES_OPEN_TAG.exec(text);
166
+ if (!open) {
167
+ throw new DocxExportError(
168
+ "malformed-xml",
169
+ `${CONTENT_TYPES_PATH} has no Types element`
170
+ );
171
+ }
172
+ const declarations = missing.map((extension) => {
173
+ const mime = MIME_BY_EXTENSION.get(extension);
174
+ return `<Default Extension="${extension}" ContentType="${mime}"/>`;
175
+ }).join("");
176
+ const at = open.index + open[0].length;
177
+ return encodeUtf8(text.slice(0, at) + declarations + text.slice(at), hadBom);
178
+ }
179
+ function planImageMedia(doc, session, relationships) {
180
+ const srcs = insertedImageSrcs(doc);
181
+ if (srcs.length === 0) return null;
182
+ const relIdByContent = imageRelIdsByContent(session, relationships.opened);
183
+ const directory = directoryOf(session.mainPartPath);
184
+ const relIdBySrc = /* @__PURE__ */ new Map();
185
+ const parts = /* @__PURE__ */ new Map();
186
+ const extensions = /* @__PURE__ */ new Set();
187
+ for (const src of srcs) {
188
+ const image = decodeImage(src);
189
+ const reused = relIdByContent.get(image.key);
190
+ if (reused !== void 0) {
191
+ relIdBySrc.set(src, reused);
192
+ continue;
193
+ }
194
+ const target = `media/image-${image.key}.${image.extension}`;
195
+ const relId = relationships.add({ type: IMAGE_REL_TYPE, target });
196
+ parts.set(directory + target, image.bytes);
197
+ extensions.add(image.extension);
198
+ relIdByContent.set(image.key, relId);
199
+ relIdBySrc.set(src, relId);
200
+ }
201
+ if (extensions.size > 0) {
202
+ const contentTypes = withImageContentTypes(session.parts, extensions);
203
+ if (contentTypes) parts.set(CONTENT_TYPES_PATH, contentTypes);
204
+ }
205
+ return { refs: imageRefs(relIdBySrc, maxDocPrId(session) + 1), parts };
206
+ }
207
+ export {
208
+ MAX_IMAGE_BYTES,
209
+ NO_IMAGES,
210
+ NO_IMAGE_REFS,
211
+ planImageMedia,
212
+ readImageSources
213
+ };
@@ -0,0 +1,22 @@
1
+ /** Reads footnote and endnote bodies related from the main document story. */
2
+ export type NoteKind = "footnote" | "endnote";
3
+ export interface ImportedNote {
4
+ kind: NoteKind;
5
+ id: string;
6
+ label: string;
7
+ text: string;
8
+ type: string | null;
9
+ }
10
+ export interface ImportedNotePart {
11
+ partPath: string | null;
12
+ ordered: readonly ImportedNote[];
13
+ byId: ReadonlyMap<string, ImportedNote>;
14
+ }
15
+ export interface ImportedNotes {
16
+ footnotes: ImportedNotePart;
17
+ endnotes: ImportedNotePart;
18
+ }
19
+ export declare const NO_NOTES: ImportedNotes;
20
+ /** Reads both note parts without modifying their original package bytes. */
21
+ export declare function readNotes(parts: Map<string, Uint8Array>, mainPartPath: string): ImportedNotes;
22
+ export declare function noteById(notes: ImportedNotes, kind: NoteKind, id: string): ImportedNote | undefined;
@@ -0,0 +1,71 @@
1
+ // src/docx/notes.ts
2
+ import {
3
+ decodeUtf8,
4
+ elementChildren,
5
+ parseXml,
6
+ R_NS,
7
+ W_NS
8
+ } from "../ooxml/xml.js";
9
+ import { readRelationships, relsPathOf, resolveTarget } from "./relationships.js";
10
+ var EMPTY_PART = {
11
+ partPath: null,
12
+ ordered: [],
13
+ byId: /* @__PURE__ */ new Map()
14
+ };
15
+ var NO_NOTES = {
16
+ footnotes: EMPTY_PART,
17
+ endnotes: EMPTY_PART
18
+ };
19
+ function attribute(el, localName) {
20
+ return Array.from(el.attributes).find((entry) => entry.localName === localName)?.value ?? null;
21
+ }
22
+ function inlineText(node) {
23
+ if (node.localName === "t") return node.textContent ?? "";
24
+ if (node.localName === "tab") return " ";
25
+ if (node.localName === "br" || node.localName === "cr") return "\n";
26
+ if (node.localName === "noBreakHyphen") return "\u2011";
27
+ if (node.localName === "softHyphen") return "\xAD";
28
+ return elementChildren(node).map(inlineText).join("");
29
+ }
30
+ function noteText(el) {
31
+ return Array.from(el.getElementsByTagNameNS(W_NS, "p")).map(inlineText).join("\n");
32
+ }
33
+ function notePart(parts, mainPartPath, kind) {
34
+ const relationshipType = `${R_NS}/${kind}s`;
35
+ const relationship = readRelationships(parts, relsPathOf(mainPartPath)).find(
36
+ (entry) => entry.type === relationshipType && !entry.external
37
+ );
38
+ if (!relationship) return EMPTY_PART;
39
+ const partPath = resolveTarget(mainPartPath, relationship.target);
40
+ const bytes = parts.get(partPath);
41
+ if (!bytes) return { ...EMPTY_PART, partPath };
42
+ const root = parseXml(decodeUtf8(bytes).text).documentElement;
43
+ const elements = elementChildren(root).filter((el) => el.localName === kind);
44
+ const ordered = elements.flatMap((el) => {
45
+ const id = attribute(el, "id");
46
+ if (id === null) return [];
47
+ const type = attribute(el, "type");
48
+ const regular = type === null || type === "normal";
49
+ const label = regular ? "?" : "";
50
+ return [{ kind, id, label, text: noteText(el), type }];
51
+ });
52
+ const byId = /* @__PURE__ */ new Map();
53
+ for (const note of ordered) {
54
+ if (!byId.has(note.id)) byId.set(note.id, note);
55
+ }
56
+ return { partPath, ordered, byId };
57
+ }
58
+ function readNotes(parts, mainPartPath) {
59
+ return {
60
+ footnotes: notePart(parts, mainPartPath, "footnote"),
61
+ endnotes: notePart(parts, mainPartPath, "endnote")
62
+ };
63
+ }
64
+ function noteById(notes, kind, id) {
65
+ return notes[`${kind}s`].byId.get(id);
66
+ }
67
+ export {
68
+ NO_NOTES,
69
+ noteById,
70
+ readNotes
71
+ };