@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,863 @@
1
+ // src/schema/docxSchema.ts
2
+ import { Schema } from "prosemirror-model";
3
+ import {
4
+ spanCount,
5
+ toCellFormat,
6
+ toCellMargins,
7
+ toColWidth,
8
+ toGridCols,
9
+ toInsideBorders,
10
+ toParagraphFormat,
11
+ toRowFormat,
12
+ toRunFormat,
13
+ toTableFormat,
14
+ toTableWidth
15
+ } from "../model/format.js";
16
+ import { toImageExtent, toImageSrc } from "../ooxml/image.js";
17
+ import { editorAttributes, editorClassNames } from "../styles/classNames.js";
18
+ import { DEFAULT_FONT_FALLBACKS } from "../styles/fontStack.js";
19
+ import {
20
+ cellStyle,
21
+ columnWidthPx,
22
+ paragraphStyle,
23
+ rowStyle,
24
+ tableStyle
25
+ } from "../styles/inlineStyle.js";
26
+ import { imageNodeSpec, runMarkSpec } from "./rendering.js";
27
+ import { imageNodeSpec as imageNodeSpec2, runMarkSpec as runMarkSpec2 } from "./rendering.js";
28
+ function text(value) {
29
+ return typeof value === "string" ? value : void 0;
30
+ }
31
+ function numberText(value) {
32
+ return typeof value === "number" ? `${value}` : void 0;
33
+ }
34
+ function parseInt10(value, fallback) {
35
+ if (value === null) return fallback;
36
+ const parsed = Number.parseInt(value, 10);
37
+ return Number.isNaN(parsed) ? fallback : parsed;
38
+ }
39
+ function parseNumberList(value) {
40
+ if (!value) return [];
41
+ return value.split(",").map((entry) => Number.parseFloat(entry)).filter((entry) => Number.isFinite(entry));
42
+ }
43
+ function numberListText(values) {
44
+ return values.length > 0 ? values.join(",") : void 0;
45
+ }
46
+ function parseJson(value) {
47
+ if (!value) return null;
48
+ try {
49
+ const parsed = JSON.parse(value);
50
+ return parsed;
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+ function formatJson(format) {
56
+ return format ? JSON.stringify(format) : void 0;
57
+ }
58
+ function isPageBreak(brAttrs) {
59
+ return typeof brAttrs === "string" && /(^|\s)(\w+:)?type="page"/.test(brAttrs);
60
+ }
61
+ function srcIdOf(dom) {
62
+ const raw = dom.getAttribute("data-src");
63
+ if (raw === null) return null;
64
+ const parsed = Number.parseInt(raw, 10);
65
+ return Number.isNaN(parsed) ? null : parsed;
66
+ }
67
+ var TABLE_PLACEHOLDER = "Table (unsupported layout, original is preserved)";
68
+ var UNKNOWN_PLACEHOLDER = "Unsupported content (not editable, original is preserved)";
69
+ var TABLE_NAMES = ["w:tbl", "tbl"];
70
+ function rawBlockDom(name) {
71
+ if (name !== void 0 && TABLE_NAMES.includes(name)) {
72
+ return {
73
+ className: editorClassNames.tablePlaceholder,
74
+ label: TABLE_PLACEHOLDER
75
+ };
76
+ }
77
+ return { className: editorClassNames.rawBlock, label: UNKNOWN_PLACEHOLDER };
78
+ }
79
+ var DOCX_RAW_SELECTOR = [
80
+ editorClassNames.rawBlock,
81
+ editorClassNames.tablePlaceholder
82
+ ].map((className) => `div[data-src].${className}`).join(", ");
83
+ var docxSchema = new Schema({
84
+ nodes: {
85
+ doc: { content: "block+" },
86
+ paragraph: {
87
+ group: "block",
88
+ content: "inline*",
89
+ // Leading and trailing whitespace carries meaning in docx text, so it is not stripped when the DOM is read back
90
+ whitespace: "pre",
91
+ attrs: {
92
+ srcId: { default: null },
93
+ /** The attribute string of the `<w:p>` opening tag. null when there is none */
94
+ pAttrs: { default: null },
95
+ /** The whole `<w:pPr>...</w:pPr>` XML. null when there is none */
96
+ pPr: { default: null },
97
+ /** The display values derived from reading pPr */
98
+ format: { default: null },
99
+ /**
100
+ * The character formatting the style this paragraph wears lays down, drawn as the
101
+ * paragraph's own CSS so that text carrying no run of its own inherits it.
102
+ * It is derived from the style table the same way `format` is, and like `format` it never
103
+ * goes back into the document.
104
+ */
105
+ styleRun: { default: null }
106
+ },
107
+ toDOM(node) {
108
+ const format = toParagraphFormat(node.attrs.format);
109
+ const styleRun = toRunFormat(node.attrs.styleRun);
110
+ return [
111
+ "p",
112
+ {
113
+ class: editorClassNames.paragraph,
114
+ style: paragraphStyle(format, styleRun),
115
+ "data-src": node.attrs.srcId === null ? void 0 : `${node.attrs.srcId}`,
116
+ "data-pattrs": text(node.attrs.pAttrs),
117
+ "data-ppr": text(node.attrs.pPr),
118
+ "data-fmt": formatJson(format),
119
+ "data-style-run": formatJson(styleRun),
120
+ [editorAttributes.pageBreakBefore]: format?.pageBreakBefore ? "" : void 0
121
+ },
122
+ 0
123
+ ];
124
+ },
125
+ parseDOM: [
126
+ {
127
+ tag: `p.${editorClassNames.paragraph}`,
128
+ getAttrs: (dom) => ({
129
+ srcId: srcIdOf(dom),
130
+ pAttrs: dom.getAttribute("data-pattrs"),
131
+ pPr: dom.getAttribute("data-ppr"),
132
+ format: toParagraphFormat(parseJson(dom.getAttribute("data-fmt"))),
133
+ styleRun: toRunFormat(
134
+ parseJson(dom.getAttribute("data-style-run"))
135
+ )
136
+ })
137
+ }
138
+ ]
139
+ },
140
+ /**
141
+ * A table carries the original `<w:tblPr>` and `<w:tblGrid>` untouched, and when an
142
+ * edited table is written back the new XML is built from those two.
143
+ */
144
+ table: {
145
+ group: "block",
146
+ content: "tableRow+",
147
+ tableRole: "table",
148
+ isolating: true,
149
+ attrs: {
150
+ srcId: { default: null },
151
+ /** The attribute string of the `<w:tbl>` opening tag */
152
+ tblAttrs: { default: null },
153
+ /** The whole `<w:tblPr>...</w:tblPr>` XML */
154
+ tblPr: { default: null },
155
+ /** The table width read out of tblPr */
156
+ tblW: { default: null },
157
+ /** The `w:gridCol` widths (dxa) in order */
158
+ gridCols: { default: [] },
159
+ format: { default: null },
160
+ /** The lines between cells the table style laid down, so an edit can derive them again */
161
+ styleInside: { default: null },
162
+ /** The cell margins the table style laid down, carried along for the same reason */
163
+ styleCellMargins: { default: null }
164
+ },
165
+ toDOM(node) {
166
+ const format = toTableFormat(node.attrs.format);
167
+ const width = toTableWidth(node.attrs.tblW);
168
+ const gridCols = toGridCols(node.attrs.gridCols);
169
+ const attrs = {
170
+ class: editorClassNames.table,
171
+ style: tableStyle(format, width),
172
+ "data-src": node.attrs.srcId === null ? void 0 : `${node.attrs.srcId}`,
173
+ "data-tblattrs": text(node.attrs.tblAttrs),
174
+ "data-tblpr": text(node.attrs.tblPr),
175
+ "data-tblw": formatJson(width),
176
+ "data-cols": numberListText(gridCols),
177
+ "data-fmt": formatJson(format),
178
+ "data-style-inside": formatJson(
179
+ toInsideBorders(node.attrs.styleInside)
180
+ ),
181
+ "data-style-margins": formatJson(
182
+ toCellMargins(node.attrs.styleCellMargins)
183
+ )
184
+ };
185
+ const body = ["tbody", 0];
186
+ if (gridCols.length === 0) return ["table", attrs, body];
187
+ const cols = gridCols.map((dxa) => [
188
+ "col",
189
+ { style: `width:${columnWidthPx(dxa)}px` }
190
+ ]);
191
+ return ["table", attrs, ["colgroup", ...cols], body];
192
+ },
193
+ parseDOM: [
194
+ // `data-cols` carries the column widths, so the colgroup we drew is not read back
195
+ { tag: "colgroup", ignore: true },
196
+ {
197
+ tag: `table.${editorClassNames.table}`,
198
+ getAttrs: (dom) => ({
199
+ srcId: srcIdOf(dom),
200
+ tblAttrs: dom.getAttribute("data-tblattrs"),
201
+ tblPr: dom.getAttribute("data-tblpr"),
202
+ tblW: toTableWidth(parseJson(dom.getAttribute("data-tblw"))),
203
+ gridCols: parseNumberList(dom.getAttribute("data-cols")),
204
+ format: toTableFormat(parseJson(dom.getAttribute("data-fmt"))),
205
+ styleInside: toInsideBorders(
206
+ parseJson(dom.getAttribute("data-style-inside"))
207
+ ),
208
+ styleCellMargins: toCellMargins(
209
+ parseJson(dom.getAttribute("data-style-margins"))
210
+ )
211
+ })
212
+ }
213
+ ]
214
+ },
215
+ tableRow: {
216
+ content: "tableCell+",
217
+ tableRole: "row",
218
+ attrs: {
219
+ /** The attribute string of the `<w:tr>` opening tag */
220
+ trAttrs: { default: null },
221
+ /** The whole `<w:tblPrEx>...</w:tblPrEx>` XML, carried along without being read */
222
+ tblPrEx: { default: null },
223
+ /** The whole `<w:trPr>...</w:trPr>` XML */
224
+ trPr: { default: null },
225
+ format: { default: null }
226
+ },
227
+ toDOM(node) {
228
+ const format = toRowFormat(node.attrs.format);
229
+ return [
230
+ "tr",
231
+ {
232
+ class: editorClassNames.tableRow,
233
+ style: rowStyle(format),
234
+ "data-trattrs": text(node.attrs.trAttrs),
235
+ "data-tblprex": text(node.attrs.tblPrEx),
236
+ "data-trpr": text(node.attrs.trPr),
237
+ "data-fmt": formatJson(format)
238
+ },
239
+ 0
240
+ ];
241
+ },
242
+ parseDOM: [
243
+ {
244
+ tag: "tr",
245
+ getAttrs: (dom) => ({
246
+ trAttrs: dom.getAttribute("data-trattrs"),
247
+ tblPrEx: dom.getAttribute("data-tblprex"),
248
+ trPr: dom.getAttribute("data-trpr"),
249
+ format: toRowFormat(parseJson(dom.getAttribute("data-fmt")))
250
+ })
251
+ }
252
+ ]
253
+ },
254
+ /**
255
+ * A vertically merged cell exists only as the one cell that starts the merge, and
256
+ * `rowspan` counts how many rows it covers.
257
+ * The empty cells on the continuing rows are rebuilt on export.
258
+ */
259
+ tableCell: {
260
+ content: "block+",
261
+ tableRole: "cell",
262
+ isolating: true,
263
+ attrs: {
264
+ colspan: { default: 1 },
265
+ rowspan: { default: 1 },
266
+ colwidth: { default: null },
267
+ /** The attribute string of the `<w:tc>` opening tag */
268
+ tcAttrs: { default: null },
269
+ /** The whole `<w:tcPr>...</w:tcPr>` XML. It still holds the original vMerge and gridSpan */
270
+ tcPr: { default: null },
271
+ /** The cell width read out of tcPr */
272
+ tcW: { default: null },
273
+ format: { default: null },
274
+ /** The opening XML of the `<w:sdt>` content control this cell sat inside */
275
+ sdtPrefix: { default: null },
276
+ /**
277
+ * The two clauses of that control's lock, which mean the same as `contentsLocked` and
278
+ * `deletionLocked` on the sdt mark. Both only ever stand alongside an `sdtPrefix`, since
279
+ * the lock lives inside that very XML.
280
+ */
281
+ sdtContentsLocked: { default: false },
282
+ sdtDeletionLocked: { default: false }
283
+ },
284
+ toDOM(node) {
285
+ const format = toCellFormat(node.attrs.format);
286
+ const colspan = spanCount(node.attrs.colspan);
287
+ const rowspan = spanCount(node.attrs.rowspan);
288
+ const colwidth = toColWidth(node.attrs.colwidth);
289
+ const locked = node.attrs.sdtContentsLocked === true;
290
+ return [
291
+ "td",
292
+ {
293
+ class: locked ? `${editorClassNames.tableCell} ${editorClassNames.cellLocked}` : editorClassNames.tableCell,
294
+ style: cellStyle(format),
295
+ colspan: colspan > 1 ? `${colspan}` : void 0,
296
+ rowspan: rowspan > 1 ? `${rowspan}` : void 0,
297
+ "data-colwidth": colwidth ? numberListText(colwidth) : void 0,
298
+ "data-tcattrs": text(node.attrs.tcAttrs),
299
+ "data-tcpr": text(node.attrs.tcPr),
300
+ "data-tcw": formatJson(toTableWidth(node.attrs.tcW)),
301
+ "data-fmt": formatJson(format),
302
+ "data-sdt-prefix": text(node.attrs.sdtPrefix),
303
+ "data-sdt-contents-locked": locked ? "1" : void 0,
304
+ "data-sdt-deletion-locked": node.attrs.sdtDeletionLocked === true ? "1" : void 0
305
+ },
306
+ 0
307
+ ];
308
+ },
309
+ parseDOM: [
310
+ {
311
+ tag: "td",
312
+ getAttrs: (dom) => ({
313
+ colspan: parseInt10(dom.getAttribute("colspan"), 1),
314
+ rowspan: parseInt10(dom.getAttribute("rowspan"), 1),
315
+ colwidth: toColWidth(
316
+ parseNumberList(dom.getAttribute("data-colwidth"))
317
+ ),
318
+ tcAttrs: dom.getAttribute("data-tcattrs"),
319
+ tcPr: dom.getAttribute("data-tcpr"),
320
+ tcW: toTableWidth(parseJson(dom.getAttribute("data-tcw"))),
321
+ format: toCellFormat(parseJson(dom.getAttribute("data-fmt"))),
322
+ sdtPrefix: dom.getAttribute("data-sdt-prefix"),
323
+ sdtContentsLocked: dom.getAttribute("data-sdt-contents-locked") === "1",
324
+ sdtDeletionLocked: dom.getAttribute("data-sdt-deletion-locked") === "1"
325
+ })
326
+ }
327
+ ]
328
+ },
329
+ /**
330
+ * The node that carries, as original XML, a block inside a table cell that we do
331
+ * not model (a nested table, for instance).
332
+ * Unlike a body block it has no original fragment number, so it carries its own
333
+ * XML around with it.
334
+ */
335
+ rawBlock: {
336
+ group: "block",
337
+ atom: true,
338
+ selectable: false,
339
+ attrs: {
340
+ xml: { default: null },
341
+ /** The original element name (for example `w:tbl`) */
342
+ name: { default: null }
343
+ },
344
+ toDOM(node) {
345
+ return [
346
+ "div",
347
+ {
348
+ class: `${editorClassNames.rawBlock} ${editorClassNames.rawXmlBlock}`,
349
+ "data-xml": text(node.attrs.xml),
350
+ "data-name": text(node.attrs.name)
351
+ },
352
+ UNKNOWN_PLACEHOLDER
353
+ ];
354
+ },
355
+ parseDOM: [
356
+ {
357
+ tag: `div.${editorClassNames.rawXmlBlock}`,
358
+ getAttrs: (dom) => ({
359
+ xml: dom.getAttribute("data-xml"),
360
+ name: dom.getAttribute("data-name")
361
+ })
362
+ }
363
+ ]
364
+ },
365
+ /** The node that carries a non-paragraph body block (a table we could not model, sectPr, an unknown element) exactly as it came */
366
+ docxRaw: {
367
+ group: "block",
368
+ atom: true,
369
+ selectable: false,
370
+ attrs: {
371
+ srcId: { default: null },
372
+ /** The original element name (for example `w:tbl`) */
373
+ name: { default: null }
374
+ },
375
+ toDOM(node) {
376
+ const { className, label } = rawBlockDom(text(node.attrs.name));
377
+ return [
378
+ "div",
379
+ {
380
+ class: className,
381
+ "data-src": node.attrs.srcId === null ? "" : `${node.attrs.srcId}`,
382
+ "data-name": text(node.attrs.name)
383
+ },
384
+ label
385
+ ];
386
+ },
387
+ parseDOM: [
388
+ {
389
+ tag: DOCX_RAW_SELECTOR,
390
+ getAttrs: (dom) => ({
391
+ srcId: srcIdOf(dom),
392
+ name: dom.getAttribute("data-name")
393
+ })
394
+ }
395
+ ]
396
+ },
397
+ /** A bookmark range marker that occurs directly under w:body rather than inside a paragraph */
398
+ bookmarkBlock: {
399
+ group: "block",
400
+ atom: true,
401
+ isolating: true,
402
+ selectable: false,
403
+ attrs: {
404
+ srcId: { default: null },
405
+ name: { default: null }
406
+ },
407
+ toDOM(node) {
408
+ return [
409
+ "div",
410
+ {
411
+ class: editorClassNames.bookmarkBlock,
412
+ "data-src": node.attrs.srcId === null ? "" : `${node.attrs.srcId}`,
413
+ "data-name": text(node.attrs.name),
414
+ hidden: "hidden"
415
+ }
416
+ ];
417
+ },
418
+ parseDOM: [
419
+ {
420
+ tag: `div.${editorClassNames.bookmarkBlock}`,
421
+ getAttrs: (dom) => ({
422
+ srcId: srcIdOf(dom),
423
+ name: dom.getAttribute("data-name")
424
+ })
425
+ }
426
+ ]
427
+ },
428
+ hardBreak: {
429
+ group: "inline",
430
+ inline: true,
431
+ marks: "run sdt link",
432
+ attrs: { brAttrs: { default: null } },
433
+ toDOM(node) {
434
+ return [
435
+ "br",
436
+ {
437
+ "data-battrs": text(node.attrs.brAttrs),
438
+ [editorAttributes.breakType]: isPageBreak(node.attrs.brAttrs) ? "page" : void 0
439
+ }
440
+ ];
441
+ },
442
+ parseDOM: [
443
+ {
444
+ tag: "br",
445
+ getAttrs: (dom) => ({ brAttrs: dom.getAttribute("data-battrs") })
446
+ }
447
+ ]
448
+ },
449
+ /**
450
+ * `src` carries the bytes themselves as a data URL (see `docx/media` for why), and
451
+ * `extent` the size the drawing records, in EMU.
452
+ * An imported image also holds its whole original `<w:drawing>` XML, so an image
453
+ * nobody touched goes back out byte for byte and a resize rewrites nothing but the
454
+ * two extents. An image inserted during editing has no such XML, and the export
455
+ * builds a drawing for it from the bytes.
456
+ */
457
+ image: {
458
+ group: "inline",
459
+ inline: true,
460
+ draggable: true,
461
+ marks: "run sdt link",
462
+ attrs: {
463
+ /** The image bytes as a data URL */
464
+ src: { default: null },
465
+ /** The display size in EMU, as `{ cx, cy }` */
466
+ extent: { default: null },
467
+ /** The alternative text from `wp:docPr descr`. null when there is none */
468
+ alt: { default: null },
469
+ /** The whole original `<w:drawing>` XML. null for an image inserted during editing */
470
+ xml: { default: null }
471
+ },
472
+ toDOM(node) {
473
+ return imageNodeSpec(node.attrs);
474
+ },
475
+ parseDOM: [
476
+ {
477
+ tag: `img.${editorClassNames.image}`,
478
+ getAttrs: (dom) => ({
479
+ src: toImageSrc(dom.getAttribute("src")),
480
+ extent: toImageExtent(parseJson(dom.getAttribute("data-extent"))),
481
+ alt: dom.getAttribute("alt") || null,
482
+ xml: dom.getAttribute("data-xml")
483
+ })
484
+ }
485
+ ]
486
+ },
487
+ commentStart: {
488
+ group: "inline",
489
+ inline: true,
490
+ atom: true,
491
+ selectable: false,
492
+ marks: "sdt link",
493
+ attrs: {
494
+ id: { default: null },
495
+ xml: { default: null }
496
+ },
497
+ toDOM(node) {
498
+ return [
499
+ "span",
500
+ {
501
+ class: editorClassNames.commentMarker,
502
+ "data-comment-marker": "start",
503
+ "data-comment-id": text(node.attrs.id),
504
+ "data-xml": text(node.attrs.xml)
505
+ }
506
+ ];
507
+ },
508
+ parseDOM: [
509
+ {
510
+ tag: `span.${editorClassNames.commentMarker}[data-comment-marker="start"]`,
511
+ getAttrs: (dom) => ({
512
+ id: dom.getAttribute("data-comment-id"),
513
+ xml: dom.getAttribute("data-xml")
514
+ })
515
+ }
516
+ ]
517
+ },
518
+ commentEnd: {
519
+ group: "inline",
520
+ inline: true,
521
+ atom: true,
522
+ selectable: false,
523
+ marks: "sdt link",
524
+ attrs: {
525
+ id: { default: null },
526
+ xml: { default: null }
527
+ },
528
+ toDOM(node) {
529
+ return [
530
+ "span",
531
+ {
532
+ class: editorClassNames.commentMarker,
533
+ "data-comment-marker": "end",
534
+ "data-comment-id": text(node.attrs.id),
535
+ "data-xml": text(node.attrs.xml)
536
+ }
537
+ ];
538
+ },
539
+ parseDOM: [
540
+ {
541
+ tag: `span.${editorClassNames.commentMarker}[data-comment-marker="end"]`,
542
+ getAttrs: (dom) => ({
543
+ id: dom.getAttribute("data-comment-id"),
544
+ xml: dom.getAttribute("data-xml")
545
+ })
546
+ }
547
+ ]
548
+ },
549
+ commentReference: {
550
+ group: "inline",
551
+ inline: true,
552
+ atom: true,
553
+ selectable: false,
554
+ marks: "run sdt link",
555
+ attrs: {
556
+ id: { default: null },
557
+ referenceXml: { default: null },
558
+ author: { default: null },
559
+ initials: { default: null },
560
+ date: { default: null },
561
+ text: { default: "" },
562
+ commentXml: { default: null },
563
+ imported: { default: false },
564
+ paraId: { default: null },
565
+ resolved: { default: false },
566
+ extensionXml: { default: null },
567
+ threadImported: { default: false },
568
+ replies: { default: [] }
569
+ },
570
+ toDOM(node) {
571
+ return [
572
+ "span",
573
+ {
574
+ class: editorClassNames.commentMarker,
575
+ "data-comment-marker": "reference",
576
+ "data-comment-id": text(node.attrs.id),
577
+ "data-reference-xml": text(node.attrs.referenceXml),
578
+ "data-comment-author": text(node.attrs.author),
579
+ "data-comment-initials": text(node.attrs.initials),
580
+ "data-comment-date": text(node.attrs.date),
581
+ "data-comment-text": text(node.attrs.text),
582
+ "data-comment-xml": text(node.attrs.commentXml),
583
+ "data-comment-imported": node.attrs.imported === true ? "1" : void 0,
584
+ "data-comment-para-id": text(node.attrs.paraId),
585
+ "data-comment-resolved": node.attrs.resolved === true ? "1" : void 0,
586
+ "data-comment-extension-xml": text(node.attrs.extensionXml),
587
+ "data-comment-thread-imported": node.attrs.threadImported === true ? "1" : void 0,
588
+ "data-comment-replies": JSON.stringify(node.attrs.replies ?? [])
589
+ }
590
+ ];
591
+ },
592
+ parseDOM: [
593
+ {
594
+ tag: `span.${editorClassNames.commentMarker}[data-comment-marker="reference"]`,
595
+ getAttrs: (dom) => ({
596
+ id: dom.getAttribute("data-comment-id"),
597
+ referenceXml: dom.getAttribute("data-reference-xml"),
598
+ author: dom.getAttribute("data-comment-author"),
599
+ initials: dom.getAttribute("data-comment-initials"),
600
+ date: dom.getAttribute("data-comment-date"),
601
+ text: dom.getAttribute("data-comment-text") ?? "",
602
+ commentXml: dom.getAttribute("data-comment-xml"),
603
+ imported: dom.getAttribute("data-comment-imported") === "1",
604
+ paraId: dom.getAttribute("data-comment-para-id"),
605
+ resolved: dom.getAttribute("data-comment-resolved") === "1",
606
+ extensionXml: dom.getAttribute("data-comment-extension-xml"),
607
+ threadImported: dom.getAttribute("data-comment-thread-imported") === "1",
608
+ replies: parseJson(dom.getAttribute("data-comment-replies")) ?? []
609
+ })
610
+ }
611
+ ]
612
+ },
613
+ noteReference: {
614
+ group: "inline",
615
+ inline: true,
616
+ atom: true,
617
+ selectable: false,
618
+ marks: "run sdt link",
619
+ attrs: {
620
+ kind: { default: "footnote" },
621
+ id: { default: null },
622
+ label: { default: "?" },
623
+ text: { default: "" },
624
+ customMarkFollows: { default: false },
625
+ referenceXml: { default: null }
626
+ },
627
+ toDOM(node) {
628
+ const kind = node.attrs.kind === "endnote" ? "Endnote" : "Footnote";
629
+ const label = text(node.attrs.label) ?? "?";
630
+ const body = text(node.attrs.text) ?? "";
631
+ return [
632
+ "sup",
633
+ {
634
+ class: editorClassNames.noteReference,
635
+ "data-note-kind": text(node.attrs.kind),
636
+ "data-note-id": text(node.attrs.id),
637
+ "data-note-label": label,
638
+ "data-note-text": body,
639
+ "data-custom-mark-follows": node.attrs.customMarkFollows === true ? "1" : void 0,
640
+ "data-reference-xml": text(node.attrs.referenceXml),
641
+ "aria-label": `${kind} ${label}`,
642
+ title: body
643
+ },
644
+ node.attrs.customMarkFollows === true ? "" : label
645
+ ];
646
+ },
647
+ parseDOM: [
648
+ {
649
+ tag: `sup.${editorClassNames.noteReference}`,
650
+ getAttrs: (dom) => ({
651
+ kind: dom.getAttribute("data-note-kind") === "endnote" ? "endnote" : "footnote",
652
+ id: dom.getAttribute("data-note-id"),
653
+ label: dom.getAttribute("data-note-label") ?? "?",
654
+ text: dom.getAttribute("data-note-text") ?? "",
655
+ customMarkFollows: dom.getAttribute("data-custom-mark-follows") === "1",
656
+ referenceXml: dom.getAttribute("data-reference-xml")
657
+ })
658
+ }
659
+ ]
660
+ },
661
+ /** The node that carries a non-run element inside a paragraph (a bookmark, for instance) exactly as it came */
662
+ rawInline: {
663
+ group: "inline",
664
+ inline: true,
665
+ atom: true,
666
+ marks: "sdt link",
667
+ attrs: { xml: { default: null } },
668
+ toDOM(node) {
669
+ return [
670
+ "span",
671
+ {
672
+ class: editorClassNames.rawInline,
673
+ "data-xml": text(node.attrs.xml)
674
+ }
675
+ ];
676
+ },
677
+ parseDOM: [
678
+ {
679
+ tag: `span.${editorClassNames.rawInline}`,
680
+ getAttrs: (dom) => ({ xml: dom.getAttribute("data-xml") })
681
+ }
682
+ ]
683
+ },
684
+ text: { group: "inline" }
685
+ },
686
+ marks: {
687
+ /**
688
+ * The content control (`w:sdt`) a stretch of inline content sits inside.
689
+ *
690
+ * It is declared ahead of the run mark on purpose: the mark declared first is drawn
691
+ * outside on screen, so one control can hold the several runs it wrapped in the file.
692
+ */
693
+ sdt: {
694
+ // A character typed against either edge of the control belongs outside it
695
+ inclusive: false,
696
+ attrs: {
697
+ /** The opening XML of the `<w:sdt>`, the same string a wrapped cell carries */
698
+ sdtPrefix: { default: null },
699
+ /**
700
+ * Which control this is, counted through the document as it was opened, and never
701
+ * written back to the file. Two controls whose XML is identical would otherwise wear
702
+ * the very same mark and their text would run into one. The first control gets 0, so
703
+ * a control made during editing needs no number of its own.
704
+ */
705
+ sdtKey: { default: 0 },
706
+ /**
707
+ * The two clauses of the control's lock: whether its contents may not be edited, and
708
+ * whether the control itself may not be deleted, not even whole. The `w:lock` inside
709
+ * sdtPrefix is where both come from, and reading it once on import saves parsing that
710
+ * string again on every draw.
711
+ * The two are independent: a control may be un-editable yet removable, or editable yet
712
+ * not removable.
713
+ */
714
+ contentsLocked: { default: false },
715
+ deletionLocked: { default: false }
716
+ },
717
+ toDOM(mark) {
718
+ const locked = mark.attrs.contentsLocked === true;
719
+ return [
720
+ "span",
721
+ {
722
+ class: locked ? `${editorClassNames.sdt} ${editorClassNames.sdtLocked}` : editorClassNames.sdt,
723
+ "data-sdt-prefix": text(mark.attrs.sdtPrefix),
724
+ "data-sdt-key": numberText(mark.attrs.sdtKey),
725
+ "data-sdt-contents-locked": locked ? "1" : void 0,
726
+ "data-sdt-deletion-locked": mark.attrs.deletionLocked === true ? "1" : void 0
727
+ },
728
+ 0
729
+ ];
730
+ },
731
+ parseDOM: [
732
+ {
733
+ tag: `span.${editorClassNames.sdt}`,
734
+ getAttrs: (dom) => {
735
+ const prefix = dom.getAttribute("data-sdt-prefix");
736
+ if (prefix === null) return false;
737
+ return {
738
+ sdtPrefix: prefix,
739
+ sdtKey: parseInt10(dom.getAttribute("data-sdt-key"), 0),
740
+ contentsLocked: dom.getAttribute("data-sdt-contents-locked") === "1",
741
+ deletionLocked: dom.getAttribute("data-sdt-deletion-locked") === "1"
742
+ };
743
+ }
744
+ }
745
+ ]
746
+ },
747
+ /**
748
+ * The hyperlink (`w:hyperlink`) a stretch of inline content sits inside.
749
+ *
750
+ * It stands between the control and the run for the same reason the control stands outside
751
+ * both: a link wraps whole runs in the file, and a link inside a content control has to come
752
+ * back out inside it (`docx/serializeParagraph`).
753
+ */
754
+ link: {
755
+ // A character typed against either edge of a link belongs outside it, and that is also what
756
+ // decides whether a caret counts as standing in one (`editor/commands/linkCommands`)
757
+ inclusive: false,
758
+ attrs: {
759
+ /**
760
+ * The opening XML of the `<w:hyperlink>`, which carries everything about the link we never
761
+ * read: `w:tooltip`, `w:history`, `w:docLocation`, `w:anchor`. null for a link made in the
762
+ * editor, which the export writes an opening tag for.
763
+ */
764
+ linkPrefix: { default: null },
765
+ /**
766
+ * The address, read through the relationship the wrapper names. null for a link that names
767
+ * a bookmark alone, or one whose relationship leads nowhere we can follow: the wrapper still
768
+ * travels, and no address is offered for it.
769
+ */
770
+ href: { default: null },
771
+ /**
772
+ * Which link this is, counted through the document as it was opened, and never written back
773
+ * to the file. Two links written exactly alike would otherwise wear the very same mark and
774
+ * the text they cover would run into one wrapper. The first link gets 0, so a link made
775
+ * during editing needs no number of its own.
776
+ */
777
+ linkKey: { default: 0 }
778
+ },
779
+ toDOM(mark) {
780
+ return [
781
+ "span",
782
+ {
783
+ class: editorClassNames.link,
784
+ // The address is drawn as data rather than as an `href`, so that nothing on the page
785
+ // navigates: a click in the text places the caret, and opening the address is offered
786
+ // by the link panel instead
787
+ "data-href": text(mark.attrs.href),
788
+ "data-link-prefix": text(mark.attrs.linkPrefix),
789
+ "data-link-key": numberText(mark.attrs.linkKey)
790
+ },
791
+ 0
792
+ ];
793
+ },
794
+ parseDOM: [
795
+ {
796
+ tag: `span.${editorClassNames.link}`,
797
+ getAttrs: (dom) => {
798
+ const prefix = dom.getAttribute("data-link-prefix");
799
+ const href = dom.getAttribute("data-href");
800
+ if (prefix === null && href === null) return false;
801
+ return {
802
+ linkPrefix: prefix,
803
+ href,
804
+ linkKey: parseInt10(dom.getAttribute("data-link-key"), 0)
805
+ };
806
+ }
807
+ }
808
+ ]
809
+ },
810
+ /**
811
+ * The run mark carries the original XML untouched, so even formatting we cannot
812
+ * interpret survives editing unchanged.
813
+ */
814
+ run: {
815
+ attrs: {
816
+ rPr: { default: null },
817
+ rAttrs: { default: null },
818
+ /** The display values derived from reading rPr */
819
+ format: { default: null }
820
+ },
821
+ toDOM(mark) {
822
+ return runMarkSpec(mark.attrs, DEFAULT_FONT_FALLBACKS);
823
+ },
824
+ parseDOM: [
825
+ {
826
+ tag: `span.${editorClassNames.run}`,
827
+ getAttrs: (dom) => ({
828
+ rAttrs: dom.getAttribute("data-rattrs"),
829
+ rPr: dom.getAttribute("data-rpr"),
830
+ format: toRunFormat(parseJson(dom.getAttribute("data-fmt")))
831
+ })
832
+ }
833
+ ]
834
+ },
835
+ /** A text tab whose mark retains the attributes of the source `w:tab`. */
836
+ tab: {
837
+ inclusive: false,
838
+ attrs: { tabAttrs: { default: null } },
839
+ toDOM(mark) {
840
+ return [
841
+ "span",
842
+ {
843
+ class: editorClassNames.tab,
844
+ "data-tattrs": text(mark.attrs.tabAttrs)
845
+ },
846
+ 0
847
+ ];
848
+ },
849
+ parseDOM: [
850
+ {
851
+ tag: `span.${editorClassNames.tab}`,
852
+ getAttrs: (dom) => ({ tabAttrs: dom.getAttribute("data-tattrs") })
853
+ }
854
+ ]
855
+ }
856
+ }
857
+ });
858
+ export {
859
+ docxSchema,
860
+ imageNodeSpec2 as imageNodeSpec,
861
+ isPageBreak,
862
+ runMarkSpec2 as runMarkSpec
863
+ };