@portone/docx-editor 0.3.0 → 0.5.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 (217) hide show
  1. package/CHANGELOG.md +205 -0
  2. package/assets/editor.png +0 -0
  3. package/dist/DocxEditor.d.ts +1 -1
  4. package/dist/DocxEditor.js +45 -25
  5. package/dist/core.d.ts +1 -1
  6. package/dist/docx/cloning.js +4 -9
  7. package/dist/docx/commentOnlyChange.d.ts +5 -3
  8. package/dist/docx/comments/grammar.d.ts +27 -10
  9. package/dist/docx/comments/grammar.js +18 -67
  10. package/dist/docx/comments/model.d.ts +5 -6
  11. package/dist/docx/comments/model.js +0 -9
  12. package/dist/docx/comments/parts.d.ts +16 -10
  13. package/dist/docx/comments/parts.js +65 -13
  14. package/dist/docx/comments/people.d.ts +11 -3
  15. package/dist/docx/comments/people.js +20 -6
  16. package/dist/docx/comments/policy.js +7 -1
  17. package/dist/docx/comments/reading.d.ts +4 -2
  18. package/dist/docx/comments/reading.js +1 -14
  19. package/dist/docx/comments/writing.js +78 -35
  20. package/dist/docx/exportDocx.js +30 -18
  21. package/dist/docx/exportRefs.d.ts +8 -3
  22. package/dist/docx/exportRefs.js +2 -1
  23. package/dist/docx/fidelity.js +24 -10
  24. package/dist/docx/fields.d.ts +42 -0
  25. package/dist/docx/fields.js +76 -0
  26. package/dist/docx/formatting/attrs.d.ts +20 -2
  27. package/dist/docx/formatting/attrs.js +57 -2
  28. package/dist/docx/formatting/context.d.ts +10 -2
  29. package/dist/docx/formatting/context.js +23 -5
  30. package/dist/docx/formatting/resolve.d.ts +10 -4
  31. package/dist/docx/formatting/resolve.js +31 -11
  32. package/dist/docx/formatting/styles.d.ts +25 -2
  33. package/dist/docx/formatting/styles.js +84 -3
  34. package/dist/docx/headersFooters.d.ts +89 -20
  35. package/dist/docx/headersFooters.js +163 -172
  36. package/dist/docx/hyperlink.d.ts +14 -4
  37. package/dist/docx/hyperlink.js +4 -1
  38. package/dist/docx/importDocx.d.ts +1 -1
  39. package/dist/docx/importDocx.js +135 -74
  40. package/dist/docx/importParagraph.d.ts +16 -4
  41. package/dist/docx/importParagraph.js +87 -93
  42. package/dist/docx/importPolicy.d.ts +70 -0
  43. package/dist/docx/importPolicy.js +190 -0
  44. package/dist/docx/importPreserved.d.ts +30 -0
  45. package/dist/docx/importPreserved.js +54 -0
  46. package/dist/docx/importTable.d.ts +2 -2
  47. package/dist/docx/importTable.js +107 -66
  48. package/dist/docx/invariants.js +42 -31
  49. package/dist/docx/newLists.d.ts +30 -0
  50. package/dist/docx/newLists.js +24 -1
  51. package/dist/docx/notes.d.ts +6 -1
  52. package/dist/docx/notes.js +6 -16
  53. package/dist/docx/numberingPlanner.d.ts +6 -3
  54. package/dist/docx/numberingPlanner.js +38 -7
  55. package/dist/docx/pageGeometry.d.ts +5 -14
  56. package/dist/docx/pageGeometry.js +0 -12
  57. package/dist/docx/protectionPolicy.d.ts +13 -5
  58. package/dist/docx/protectionPolicy.js +32 -22
  59. package/dist/docx/scan.d.ts +18 -8
  60. package/dist/docx/scan.js +17 -11
  61. package/dist/docx/sections.d.ts +126 -0
  62. package/dist/docx/sections.js +207 -0
  63. package/dist/docx/serializeBlock.d.ts +13 -4
  64. package/dist/docx/serializeBlock.js +16 -18
  65. package/dist/docx/serializeParagraph.d.ts +4 -0
  66. package/dist/docx/serializeParagraph.js +1 -0
  67. package/dist/docx/serializePreserved.d.ts +14 -0
  68. package/dist/docx/serializePreserved.js +24 -0
  69. package/dist/docx/serializeStory.d.ts +17 -0
  70. package/dist/docx/serializeStory.js +17 -0
  71. package/dist/docx/serializeTable.js +10 -13
  72. package/dist/docx/session.d.ts +24 -7
  73. package/dist/docx/session.js +37 -6
  74. package/dist/docx/story.d.ts +140 -0
  75. package/dist/docx/story.js +237 -0
  76. package/dist/docx/storyProjection.js +6 -1
  77. package/dist/docx/tableFormatting/conditions.d.ts +76 -0
  78. package/dist/docx/tableFormatting/conditions.js +196 -0
  79. package/dist/docx/tableFormatting/editing.d.ts +7 -3
  80. package/dist/docx/tableFormatting/editing.js +4 -5
  81. package/dist/docx/tableFormatting/reading.d.ts +49 -19
  82. package/dist/docx/tableFormatting/reading.js +109 -35
  83. package/dist/docx/tableFormatting.d.ts +1 -0
  84. package/dist/docx/tableFormatting.js +1 -0
  85. package/dist/docx/tableTemplate.js +12 -12
  86. package/dist/editor/clipboard/htmlReader.d.ts +30 -0
  87. package/dist/editor/clipboard/htmlReader.js +302 -0
  88. package/dist/editor/clipboard/internalChannel.d.ts +57 -0
  89. package/dist/editor/clipboard/internalChannel.js +58 -0
  90. package/dist/editor/clipboard/normalizers.d.ts +99 -0
  91. package/dist/editor/clipboard/normalizers.js +199 -0
  92. package/dist/editor/clipboard/parser.d.ts +34 -0
  93. package/dist/editor/clipboard/parser.js +58 -0
  94. package/dist/editor/clipboard/plugin.d.ts +21 -0
  95. package/dist/editor/clipboard/plugin.js +320 -0
  96. package/dist/editor/clipboard/readContext.d.ts +24 -0
  97. package/dist/editor/clipboard/readContext.js +19 -0
  98. package/dist/editor/clipboard/readers.d.ts +33 -0
  99. package/dist/editor/clipboard/readers.js +37 -0
  100. package/dist/editor/commands/comments/editing.d.ts +26 -6
  101. package/dist/editor/commands/comments/editing.js +175 -105
  102. package/dist/editor/commands/comments/model.d.ts +34 -17
  103. package/dist/editor/commands/comments/model.js +11 -0
  104. package/dist/editor/commands/comments/reading.d.ts +5 -3
  105. package/dist/editor/commands/comments/reading.js +8 -58
  106. package/dist/editor/commands/formatting/propertyCommands.js +6 -1
  107. package/dist/editor/commands/index.d.ts +2 -2
  108. package/dist/editor/commands/index.js +2 -0
  109. package/dist/editor/commands/listCommands.d.ts +12 -3
  110. package/dist/editor/commands/listCommands.js +76 -30
  111. package/dist/editor/commands/noteQueries.d.ts +22 -5
  112. package/dist/editor/commands/noteQueries.js +34 -6
  113. package/dist/editor/commands/paragraphCommands.js +6 -1
  114. package/dist/editor/createEditor.js +14 -4
  115. package/dist/editor/documentStyles.d.ts +26 -4
  116. package/dist/editor/documentStyles.js +9 -4
  117. package/dist/editor/editorDocument.d.ts +7 -6
  118. package/dist/editor/editorDocument.js +18 -6
  119. package/dist/editor/imageFiles.d.ts +2 -2
  120. package/dist/editor/imageFiles.js +2 -0
  121. package/dist/editor/insertTable.d.ts +1 -1
  122. package/dist/editor/insertTable.js +2 -2
  123. package/dist/editor/paragraphEdits.d.ts +16 -1
  124. package/dist/editor/paragraphEdits.js +13 -5
  125. package/dist/editor/paragraphPlacement.d.ts +11 -0
  126. package/dist/editor/paragraphPlacement.js +18 -0
  127. package/dist/editor/plainText.d.ts +12 -0
  128. package/dist/editor/plainText.js +2 -1
  129. package/dist/editor/plugins/columnResize.js +6 -3
  130. package/dist/editor/plugins/commentComposer.d.ts +28 -0
  131. package/dist/editor/plugins/commentComposer.js +46 -0
  132. package/dist/editor/plugins/commentDecorations.d.ts +29 -2
  133. package/dist/editor/plugins/commentDecorations.js +89 -15
  134. package/dist/editor/plugins/documentProjection.d.ts +31 -0
  135. package/dist/editor/plugins/documentProjection.js +22 -0
  136. package/dist/editor/plugins/imagePaste.js +20 -10
  137. package/dist/editor/plugins/linkPanel.d.ts +7 -3
  138. package/dist/editor/plugins/linkPanel.js +13 -27
  139. package/dist/editor/plugins/numberingDecorations.d.ts +10 -4
  140. package/dist/editor/plugins/numberingDecorations.js +43 -2
  141. package/dist/editor/plugins/panelState.d.ts +67 -0
  142. package/dist/editor/plugins/panelState.js +54 -0
  143. package/dist/editor/plugins/paragraphDisplay.js +9 -3
  144. package/dist/editor/plugins/tableContextMenu.d.ts +1 -1
  145. package/dist/editor/plugins/tableContextMenu.js +30 -47
  146. package/dist/editor/plugins/tableDisplay.js +19 -5
  147. package/dist/editor/plugins/textContextMenu.d.ts +1 -1
  148. package/dist/editor/plugins/textContextMenu.js +30 -47
  149. package/dist/model/format.d.ts +50 -0
  150. package/dist/model/format.js +65 -0
  151. package/dist/numbering/listRegistry.d.ts +37 -0
  152. package/dist/numbering/listRegistry.js +112 -0
  153. package/dist/numbering/listTemplate.d.ts +26 -17
  154. package/dist/numbering/listTemplate.js +66 -20
  155. package/dist/numbering/markers.d.ts +15 -6
  156. package/dist/numbering/markers.js +26 -59
  157. package/dist/numbering/parseNumbering.d.ts +70 -5
  158. package/dist/numbering/parseNumbering.js +100 -26
  159. package/dist/numbering/spellers.d.ts +15 -0
  160. package/dist/numbering/spellers.js +96 -0
  161. package/dist/numbering/writeNumbering.d.ts +5 -3
  162. package/dist/numbering/writeNumbering.js +15 -15
  163. package/dist/ooxml/conformance.d.ts +28 -0
  164. package/dist/ooxml/conformance.js +20 -0
  165. package/dist/ooxml/errors.d.ts +5 -5
  166. package/dist/ooxml/fragment.d.ts +11 -0
  167. package/dist/ooxml/fragment.js +14 -4
  168. package/dist/ooxml/image.d.ts +3 -4
  169. package/dist/ooxml/image.js +50 -5
  170. package/dist/ooxml/names.d.ts +15 -0
  171. package/dist/ooxml/names.js +10 -1
  172. package/dist/ooxml/partSplice.d.ts +1 -1
  173. package/dist/ooxml/partSplice.js +10 -3
  174. package/dist/ooxml/props.d.ts +8 -0
  175. package/dist/ooxml/props.js +14 -4
  176. package/dist/ooxml/rangeMarkers.d.ts +5 -0
  177. package/dist/ooxml/rangeMarkers.js +24 -0
  178. package/dist/ooxml/xml.d.ts +8 -9
  179. package/dist/ooxml/xml.js +6 -6
  180. package/dist/page/PageGuides.d.ts +8 -4
  181. package/dist/page/PageGuides.js +13 -37
  182. package/dist/page/pageLayout.d.ts +62 -13
  183. package/dist/page/pageLayout.js +91 -37
  184. package/dist/page/usePageLayout.d.ts +14 -11
  185. package/dist/page/usePageLayout.js +21 -29
  186. package/dist/schema/attrRoles.js +44 -19
  187. package/dist/schema/docxSchema.d.ts +9 -1
  188. package/dist/schema/docxSchema.js +220 -139
  189. package/dist/schema/editGuard.d.ts +1 -1
  190. package/dist/schema/guards.js +2 -2
  191. package/dist/schema/index.d.ts +1 -0
  192. package/dist/schema/preservedFragments.d.ts +12 -0
  193. package/dist/schema/preservedFragments.js +38 -0
  194. package/dist/schema/preservedGuards.d.ts +9 -7
  195. package/dist/schema/preservedGuards.js +112 -11
  196. package/dist/schema/protection.d.ts +34 -5
  197. package/dist/schema/protection.js +42 -14
  198. package/dist/schema/rendering.js +3 -1
  199. package/dist/schema/stories.d.ts +49 -0
  200. package/dist/schema/stories.js +78 -0
  201. package/dist/styles/classNames.d.ts +16 -7
  202. package/dist/styles/classNames.js +16 -7
  203. package/dist/styles.css +90 -30
  204. package/dist/table/cellFormatting.js +1 -2
  205. package/dist/table/gridBorders.d.ts +11 -15
  206. package/dist/table/gridBorders.js +32 -18
  207. package/dist/table/resize.d.ts +5 -3
  208. package/dist/ui/CommentsPanel.d.ts +1 -3
  209. package/dist/ui/CommentsPanel.js +24 -15
  210. package/dist/ui/NotesPanel.js +2 -2
  211. package/dist/ui/TextMenu.d.ts +1 -3
  212. package/dist/ui/TextMenu.js +10 -6
  213. package/dist/ui/comments/CommentComposer.d.ts +6 -1
  214. package/dist/ui/comments/CommentComposer.js +26 -3
  215. package/package.json +1 -1
  216. package/dist/editor/externalClipboard.d.ts +0 -11
  217. package/dist/editor/externalClipboard.js +0 -456
@@ -0,0 +1,190 @@
1
+ // src/docx/importPolicy.ts
2
+ import { M_NS, W_NS } from "../ooxml/names.js";
3
+ import {
4
+ COMMENT_RANGE_MARKERS,
5
+ PERMISSION_MARKERS,
6
+ RANGE_MARKERS
7
+ } from "../ooxml/rangeMarkers.js";
8
+ var MODEL = { tier: "model" };
9
+ var HIDDEN_MARKER = {
10
+ tier: "marker",
11
+ display: "hidden",
12
+ guarded: true
13
+ };
14
+ var IGNORABLE = {
15
+ tier: "ignorable",
16
+ display: "hidden",
17
+ guarded: false
18
+ };
19
+ function chip(tier) {
20
+ return { tier, display: "chip", guarded: false };
21
+ }
22
+ var RUN_CHIP = chip("runContent");
23
+ var INLINE_CHIP = chip("inline");
24
+ var BLOCK_CHIP = chip("block");
25
+ var FIELD_PIECE = {
26
+ tier: "runContent",
27
+ display: "chip",
28
+ guarded: true
29
+ };
30
+ function clarkName(el) {
31
+ return `{${el.namespaceURI ?? ""}}${el.localName}`;
32
+ }
33
+ function wml(localName) {
34
+ return `{${W_NS}}${localName}`;
35
+ }
36
+ function rules(entries) {
37
+ return new Map(
38
+ entries.flatMap(
39
+ ([names, policy]) => names.map((name) => [wml(name), policy])
40
+ )
41
+ );
42
+ }
43
+ var REVISION_CONTAINERS = ["ins", "del", "moveFrom", "moveTo"];
44
+ var MATH = [`{${M_NS}}oMath`, `{${M_NS}}oMathPara`];
45
+ var RUN_LEVEL = rules([
46
+ [["rPr", "t", "br", "tab", "drawing"], MODEL],
47
+ [["commentReference", "footnoteReference", "endnoteReference"], MODEL],
48
+ [["lastRenderedPageBreak"], IGNORABLE],
49
+ [["softHyphen"], { tier: "runContent", display: "hidden", guarded: false }],
50
+ [
51
+ ["noBreakHyphen"],
52
+ { tier: "runContent", display: "text", text: "\u2011", guarded: false }
53
+ ],
54
+ [["cr"], { tier: "runContent", display: "break", guarded: false }],
55
+ // §17.16.18: a complex field is the begin, the instruction and the end read in order, so a
56
+ // piece taken away leaves the rest saying something the file never said
57
+ [["fldChar", "instrText", "delInstrText"], FIELD_PIECE],
58
+ [
59
+ [
60
+ "sym",
61
+ "ptab",
62
+ "pgNum",
63
+ "pict",
64
+ "object",
65
+ "ruby",
66
+ "contentPart",
67
+ "annotationRef",
68
+ "footnoteRef",
69
+ "endnoteRef",
70
+ "separator",
71
+ "continuationSeparator",
72
+ "delText",
73
+ "dayShort",
74
+ "monthShort",
75
+ "yearShort",
76
+ "dayLong",
77
+ "monthLong",
78
+ "yearLong"
79
+ ],
80
+ RUN_CHIP
81
+ ]
82
+ ]);
83
+ var PARAGRAPH_CHILDREN = [
84
+ [RANGE_MARKERS, HIDDEN_MARKER],
85
+ [PERMISSION_MARKERS, HIDDEN_MARKER],
86
+ [["proofErr"], IGNORABLE],
87
+ [REVISION_CONTAINERS, INLINE_CHIP],
88
+ [["fldSimple", "smartTag", "customXml", "dir", "bdo", "subDoc"], INLINE_CHIP]
89
+ ];
90
+ var PARAGRAPH_LEVEL = new Map([
91
+ ...rules([
92
+ [["pPr", "r", "hyperlink", "sdt"], MODEL],
93
+ [COMMENT_RANGE_MARKERS, MODEL],
94
+ ...PARAGRAPH_CHILDREN
95
+ ]),
96
+ ...MATH.map((name) => [name, INLINE_CHIP])
97
+ ]);
98
+ var WRAPPER_LEVEL = new Map([
99
+ ...rules([
100
+ [["r", "hyperlink"], MODEL],
101
+ [COMMENT_RANGE_MARKERS, MODEL],
102
+ [["sdt"], INLINE_CHIP],
103
+ ...PARAGRAPH_CHILDREN
104
+ ]),
105
+ ...MATH.map((name) => [name, INLINE_CHIP])
106
+ ]);
107
+ var BLOCK_CHILDREN = [
108
+ [["p", "tbl"], MODEL],
109
+ [RANGE_MARKERS, HIDDEN_MARKER],
110
+ [COMMENT_RANGE_MARKERS, HIDDEN_MARKER],
111
+ [PERMISSION_MARKERS, HIDDEN_MARKER],
112
+ [["proofErr"], IGNORABLE],
113
+ [REVISION_CONTAINERS, BLOCK_CHIP],
114
+ [["sdt", "customXml", "altChunk"], BLOCK_CHIP]
115
+ ];
116
+ var BODY_LEVEL = new Map([
117
+ ...rules([...BLOCK_CHILDREN, [["sectPr"], BLOCK_CHIP]]),
118
+ ...MATH.map((name) => [name, BLOCK_CHIP])
119
+ ]);
120
+ var CELL_LEVEL = new Map([
121
+ ...rules([...BLOCK_CHILDREN, [["tcPr"], MODEL]]),
122
+ ...MATH.map((name) => [name, BLOCK_CHIP])
123
+ ]);
124
+ var TABLE_LEVEL = rules([
125
+ [["tblPr", "tblGrid", "tr"], MODEL],
126
+ [RANGE_MARKERS, HIDDEN_MARKER],
127
+ [COMMENT_RANGE_MARKERS, HIDDEN_MARKER],
128
+ [PERMISSION_MARKERS, HIDDEN_MARKER],
129
+ [["proofErr"], IGNORABLE]
130
+ ]);
131
+ var ROW_LEVEL = rules([
132
+ [["tblPrEx", "trPr", "tc", "sdt"], MODEL],
133
+ [RANGE_MARKERS, HIDDEN_MARKER],
134
+ [COMMENT_RANGE_MARKERS, HIDDEN_MARKER],
135
+ [PERMISSION_MARKERS, HIDDEN_MARKER],
136
+ [["proofErr"], IGNORABLE]
137
+ ]);
138
+ var WML_POLICY = {
139
+ r: RUN_LEVEL,
140
+ p: PARAGRAPH_LEVEL,
141
+ wrapper: WRAPPER_LEVEL,
142
+ body: BODY_LEVEL,
143
+ tc: CELL_LEVEL,
144
+ tbl: TABLE_LEVEL,
145
+ tr: ROW_LEVEL
146
+ };
147
+ var LEVEL_PRESERVATION = {
148
+ r: RUN_CHIP,
149
+ p: INLINE_CHIP,
150
+ wrapper: INLINE_CHIP,
151
+ body: BLOCK_CHIP,
152
+ tc: BLOCK_CHIP
153
+ };
154
+ function defaultPreservation(level) {
155
+ return LEVEL_PRESERVATION[level];
156
+ }
157
+ var LEVEL_DEFAULTS = {
158
+ ...LEVEL_PRESERVATION,
159
+ tbl: { tier: "demote" },
160
+ tr: { tier: "demote" }
161
+ };
162
+ function policyFor(el, level) {
163
+ return WML_POLICY[level].get(clarkName(el)) ?? LEVEL_DEFAULTS[level];
164
+ }
165
+ function runContentText(el) {
166
+ const policy = policyFor(el, "r");
167
+ if (policy.tier === "model") {
168
+ switch (el.localName) {
169
+ case "t":
170
+ return el.textContent ?? "";
171
+ case "tab":
172
+ return " ";
173
+ case "br":
174
+ return "\n";
175
+ // A drawing and the three annotation references draw something that is not text
176
+ default:
177
+ return null;
178
+ }
179
+ }
180
+ if (policy.tier === "demote") return null;
181
+ if (policy.display === "break") return "\n";
182
+ return policy.display === "text" ? policy.text ?? null : null;
183
+ }
184
+ export {
185
+ WML_POLICY,
186
+ clarkName,
187
+ defaultPreservation,
188
+ policyFor,
189
+ runContentText
190
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * One element kept exactly as it came, at whatever level of the document it stood.
3
+ *
4
+ * `./importPolicy` says what an element is worth keeping as; this is where that answer becomes a
5
+ * node. Every level has a node of its own - inside a run, beside the runs of a paragraph, and in
6
+ * the place of a block - so the three readers build them the same way and cannot drift apart in
7
+ * what a chip shows or which fragments a guard answers for.
8
+ */
9
+ import type { Mark, Node as PMNode } from "prosemirror-model";
10
+ import { type DemotionPolicy, type ElementPolicy, type PreservationRule, type PreservingLevel } from "./importPolicy";
11
+ /**
12
+ * The rule an element is kept under.
13
+ *
14
+ * The level's own narrowest preservation stands in wherever the table said `model` and the reader
15
+ * could not read the element after all, so a structure it could not take apart costs that element
16
+ * and no more.
17
+ */
18
+ export declare function preservationOf(policy: ElementPolicy | DemotionPolicy, level: PreservingLevel): PreservationRule;
19
+ /** One child of a run kept as it came, wearing the run mark so it goes back inside that run */
20
+ export declare function buildPreservedRunContent(el: Element, marks: readonly Mark[], rule: PreservationRule): PMNode;
21
+ /** One child of a paragraph, or of a wrapper inside it, kept as it came */
22
+ export declare function buildPreservedInline(el: Element, wrappers: readonly Mark[], rule: PreservationRule): PMNode;
23
+ /**
24
+ * One block kept as it came, standing where it stood.
25
+ *
26
+ * A body block is one of the fragments the session holds, so it names that fragment and the bytes
27
+ * it arrived as go back out untouched. A block inside a cell was never a fragment of its own, so
28
+ * it carries its XML along with it.
29
+ */
30
+ export declare function buildPreservedBlock(el: Element, srcId: string | null, level: "body" | "tc"): PMNode;
@@ -0,0 +1,54 @@
1
+ // src/docx/importPreserved.ts
2
+ import { serializeXml } from "../ooxml/xml.js";
3
+ import { docxSchema } from "../schema/index.js";
4
+ import {
5
+ defaultPreservation,
6
+ policyFor
7
+ } from "./importPolicy.js";
8
+ function preservedText(el, rule) {
9
+ if (rule.display === "text") return rule.text ?? null;
10
+ if (rule.display !== "chip") return null;
11
+ return el.textContent === "" ? null : el.textContent ?? null;
12
+ }
13
+ function preservedAttrs(el, rule) {
14
+ return {
15
+ xml: serializeXml(el),
16
+ element: el.localName,
17
+ display: rule.display,
18
+ text: preservedText(el, rule),
19
+ guarded: rule.guarded
20
+ };
21
+ }
22
+ function preservationOf(policy, level) {
23
+ return policy.tier === "model" || policy.tier === "demote" ? defaultPreservation(level) : policy;
24
+ }
25
+ function buildPreservedRunContent(el, marks, rule) {
26
+ return docxSchema.nodes.rawRunContent.create(
27
+ preservedAttrs(el, rule),
28
+ null,
29
+ marks
30
+ );
31
+ }
32
+ function buildPreservedInline(el, wrappers, rule) {
33
+ return docxSchema.nodes.rawInline.create(
34
+ preservedAttrs(el, rule),
35
+ null,
36
+ wrappers
37
+ );
38
+ }
39
+ function buildPreservedBlock(el, srcId, level) {
40
+ const rule = preservationOf(policyFor(el, level), level);
41
+ return docxSchema.nodes.rawBlock.create({
42
+ xml: srcId === null ? serializeXml(el) : null,
43
+ srcId,
44
+ name: el.nodeName,
45
+ display: rule.display,
46
+ guarded: rule.guarded
47
+ });
48
+ }
49
+ export {
50
+ buildPreservedBlock,
51
+ buildPreservedInline,
52
+ buildPreservedRunContent,
53
+ preservationOf
54
+ };
@@ -3,7 +3,7 @@
3
3
  * values for display. Unsupported grids return null so the caller can preserve their source XML.
4
4
  */
5
5
  import type { Node as PMNode } from "prosemirror-model";
6
- import { type StyleTable } from "./formatting";
6
+ import { type FormattingContext } from "./formatting";
7
7
  import { type ImportSources } from "./importParagraph";
8
8
  /** Moves a `<w:tbl>` into a table node. null if it cannot be modelled */
9
- export declare function buildTable(el: Element, srcId: string | null, sources?: ImportSources, styles?: StyleTable, defaultTableStyleId?: string | null): PMNode | null;
9
+ export declare function buildTable(el: Element, srcId: string | null, sources?: ImportSources, context?: FormattingContext): PMNode | null;
@@ -1,8 +1,4 @@
1
1
  // src/docx/importTable.ts
2
- import {
3
- toCellMargins,
4
- toInsideBorders
5
- } from "../model/format.js";
6
2
  import { childValue, wAttr } from "../ooxml/units.js";
7
3
  import {
8
4
  attrString,
@@ -13,29 +9,45 @@ import {
13
9
  import { docxSchema } from "../schema/index.js";
14
10
  import {
15
11
  layerTableFormat,
16
- NO_STYLES
12
+ NO_FORMATTING,
13
+ styledParagraph,
14
+ tableStyleAttrs,
15
+ tableStyleFor
17
16
  } from "./formatting.js";
18
17
  import {
19
18
  buildParagraph,
20
19
  NO_IMPORT_SOURCES
21
20
  } from "./importParagraph.js";
21
+ import { policyFor } from "./importPolicy.js";
22
+ import { buildPreservedBlock } from "./importPreserved.js";
22
23
  import { readSdtWrapper } from "./sdt.js";
23
24
  import {
24
- cellBorderDefaults,
25
- gridEdgesOf,
25
+ cellConditionsOf,
26
+ cellDefaultsFor,
27
+ layerBandSizes,
26
28
  layerCellMargins,
27
29
  layerInsideBorders,
30
+ NO_BAND_SIZES,
28
31
  NO_CELL_MARGINS,
29
32
  NO_INSIDE_BORDERS,
33
+ readBandSizes,
30
34
  readCellFormat,
31
35
  readCellMarginsOf,
32
36
  readGridCols,
33
37
  readInsideBorders,
34
38
  readRowFormat,
35
39
  readTableFormat,
40
+ readTableLook,
36
41
  readTableWidth,
37
42
  tblStyleIdOf
38
43
  } from "./tableFormatting.js";
44
+ function isTransparent(el, level) {
45
+ const tier = policyFor(el, level).tier;
46
+ return tier === "marker" || tier === "ignorable";
47
+ }
48
+ function takeGathered(gathered) {
49
+ return gathered.length === 0 ? null : gathered.splice(0).join("");
50
+ }
39
51
  function readGridSpan(tcPr) {
40
52
  const value = tcPr ? childValue(tcPr, "gridSpan") : null;
41
53
  const parsed = value === null ? null : Number.parseInt(value, 10);
@@ -64,27 +76,45 @@ function readSdtCell(el) {
64
76
  }
65
77
  };
66
78
  }
79
+ function trailCell(cells, gathered) {
80
+ const xml = takeGathered(gathered);
81
+ if (xml === null) return true;
82
+ const last = cells.at(-1);
83
+ if (!last || last.vMerge === "continue") return false;
84
+ last.trailingXml = (last.trailingXml ?? "") + xml;
85
+ return true;
86
+ }
67
87
  function readRow(el) {
68
88
  const cells = [];
89
+ const gathered = [];
69
90
  let tblPrEx = null;
91
+ let leadingXml = null;
70
92
  for (const child of elementChildren(el)) {
71
93
  if (child.localName === "trPr") continue;
72
94
  if (child.localName === "tblPrEx") {
73
95
  tblPrEx = child;
74
96
  continue;
75
97
  }
98
+ if (isTransparent(child, "tr")) {
99
+ gathered.push(serializeXml(child));
100
+ continue;
101
+ }
76
102
  const sdt = child.localName === "sdt" ? readSdtCell(child) : null;
77
103
  if (!sdt && child.localName !== "tc") return null;
104
+ if (cells.length === 0) leadingXml = takeGathered(gathered);
105
+ else if (!trailCell(cells, gathered)) return null;
78
106
  const tc = sdt ? sdt.el : child;
79
107
  const tcPr = childByLocalName(tc, "tcPr");
80
108
  cells.push({
81
109
  el: tc,
82
110
  gridSpan: readGridSpan(tcPr),
83
111
  vMerge: readVerticalMerge(tcPr),
84
- control: sdt ? sdt.control : null
112
+ control: sdt ? sdt.control : null,
113
+ trailingXml: null
85
114
  });
86
115
  }
87
- return cells.length > 0 ? { el, tblPrEx, cells } : null;
116
+ if (cells.length === 0 || !trailCell(cells, gathered)) return null;
117
+ return { el, tblPrEx, cells, leadingXml, trailingXml: null };
88
118
  }
89
119
  function gridRevisionXml(grid) {
90
120
  const revision = childByLocalName(grid, "tblGridChange");
@@ -104,6 +134,8 @@ function readTableParts(el) {
104
134
  let tblGrid = null;
105
135
  let gridChange = null;
106
136
  const rows = [];
137
+ const gathered = [];
138
+ let leadingXml = null;
107
139
  for (const child of elementChildren(el)) {
108
140
  if (child.localName === "tblPr") {
109
141
  tblPr = child;
@@ -114,12 +146,22 @@ function readTableParts(el) {
114
146
  gridChange = gridRevisionXml(child);
115
147
  continue;
116
148
  }
149
+ if (isTransparent(child, "tbl")) {
150
+ gathered.push(serializeXml(child));
151
+ continue;
152
+ }
117
153
  if (child.localName !== "tr") return null;
118
154
  const row = readRow(child);
119
155
  if (!row) return null;
156
+ const previous = rows.at(-1);
157
+ if (previous) previous.trailingXml = takeGathered(gathered);
158
+ else leadingXml = takeGathered(gathered);
120
159
  rows.push(row);
121
160
  }
122
- return rows.length > 0 ? { tblPr, tblGrid, gridChange, rows } : null;
161
+ const last = rows.at(-1);
162
+ if (!last) return null;
163
+ last.trailingXml = takeGathered(gathered);
164
+ return { tblPr, tblGrid, gridChange, rows, leadingXml };
123
165
  }
124
166
  function resolveVerticalMerges(rows, width) {
125
167
  const drafts = [];
@@ -141,7 +183,8 @@ function resolveVerticalMerges(rows, width) {
141
183
  col,
142
184
  colspan: cell.gridSpan,
143
185
  rowspan: 1,
144
- control: cell.control
186
+ control: cell.control,
187
+ trailingXml: cell.trailingXml
145
188
  };
146
189
  rowDrafts.push(draft);
147
190
  if (cell.vMerge === "restart") next.set(col, draft);
@@ -162,37 +205,31 @@ function gridWidthOf(rows) {
162
205
  const first = widths[0];
163
206
  return widths.every((width) => width === first) ? first : null;
164
207
  }
165
- function buildCellBlock(el, sources) {
208
+ function buildCellBlock(el, sources, context, placement) {
166
209
  if (el.localName === "p") {
167
- const paragraph = buildParagraph(el, null, sources);
168
- if (paragraph) return paragraph;
210
+ return styledParagraph(
211
+ buildParagraph(el, null, sources),
212
+ context,
213
+ placement
214
+ );
169
215
  }
170
- return docxSchema.nodes.rawBlock.create({
171
- xml: serializeXml(el),
172
- name: el.nodeName
173
- });
216
+ return buildPreservedBlock(el, null, "tc");
174
217
  }
175
- function cellBorderDefaultsFor(draft, lines) {
176
- return cellBorderDefaults(
177
- gridEdgesOf(
178
- {
179
- top: draft.row,
180
- bottom: draft.row + draft.rowspan,
181
- left: draft.col,
182
- right: draft.col + draft.colspan
183
- },
184
- lines
185
- ),
186
- lines.outer,
187
- lines.inside
188
- );
218
+ function cellRect(draft) {
219
+ return {
220
+ top: draft.row,
221
+ bottom: draft.row + draft.rowspan,
222
+ left: draft.col,
223
+ right: draft.col + draft.colspan
224
+ };
189
225
  }
190
- function buildCell(draft, lines, sources) {
226
+ function buildCell(draft, table, sources, context) {
191
227
  const tcPr = childByLocalName(draft.el, "tcPr");
228
+ const defaults = cellDefaultsFor(cellRect(draft), table.grid, table.sources);
192
229
  const blocks = [];
193
230
  for (const child of elementChildren(draft.el)) {
194
231
  if (child.localName === "tcPr") continue;
195
- blocks.push(buildCellBlock(child, sources));
232
+ blocks.push(buildCellBlock(child, sources, context, defaults.placement));
196
233
  }
197
234
  if (blocks.length === 0) return null;
198
235
  return docxSchema.nodes.tableCell.create(
@@ -203,22 +240,19 @@ function buildCell(draft, lines, sources) {
203
240
  tcAttrs: attrString(draft.el),
204
241
  tcPr: tcPr ? serializeXml(tcPr) : null,
205
242
  tcW: readTableWidth(tcPr, "tcW"),
206
- format: readCellFormat(
207
- tcPr,
208
- cellBorderDefaultsFor(draft, lines),
209
- lines.margins
210
- ),
243
+ format: readCellFormat(tcPr, defaults),
211
244
  sdtPrefix: draft.control?.prefix ?? null,
212
245
  sdtContentsLocked: draft.control?.contentsLocked ?? false,
213
- sdtDeletionLocked: draft.control?.deletionLocked ?? false
246
+ sdtDeletionLocked: draft.control?.deletionLocked ?? false,
247
+ trailingXml: draft.trailingXml
214
248
  },
215
249
  blocks
216
250
  );
217
251
  }
218
- function buildRow(row, drafts, lines, sources) {
252
+ function buildRow(row, drafts, table, sources, context) {
219
253
  const cells = [];
220
254
  for (const draft of drafts) {
221
- const cell = buildCell(draft, lines, sources);
255
+ const cell = buildCell(draft, table, sources, context);
222
256
  if (!cell) return null;
223
257
  cells.push(cell);
224
258
  }
@@ -228,16 +262,14 @@ function buildRow(row, drafts, lines, sources) {
228
262
  trAttrs: attrString(row.el),
229
263
  tblPrEx: row.tblPrEx ? serializeXml(row.tblPrEx) : null,
230
264
  trPr: trPr ? serializeXml(trPr) : null,
231
- format: readRowFormat(trPr)
265
+ format: readRowFormat(trPr),
266
+ leadingXml: row.leadingXml,
267
+ trailingXml: row.trailingXml
232
268
  },
233
269
  cells
234
270
  );
235
271
  }
236
- function tableStyleOf(tblPr, styles, defaultTableStyleId) {
237
- const styleId = tblStyleIdOf(tblPr);
238
- return (styleId !== null ? styles.get(styleId) : void 0) ?? (defaultTableStyleId !== null ? styles.get(defaultTableStyleId) : void 0);
239
- }
240
- function buildTable(el, srcId, sources = NO_IMPORT_SOURCES, styles = NO_STYLES, defaultTableStyleId = null) {
272
+ function buildTable(el, srcId, sources = NO_IMPORT_SOURCES, context = NO_FORMATTING) {
241
273
  const parts = readTableParts(el);
242
274
  if (!parts) return null;
243
275
  const gridCols = readGridCols(parts.tblGrid);
@@ -246,27 +278,38 @@ function buildTable(el, srcId, sources = NO_IMPORT_SOURCES, styles = NO_STYLES,
246
278
  if (gridCols.length > 0 && gridCols.length !== width) return null;
247
279
  const drafts = resolveVerticalMerges(parts.rows, width);
248
280
  if (!drafts) return null;
249
- const style = tableStyleOf(parts.tblPr, styles, defaultTableStyleId);
281
+ const styleId = tblStyleIdOf(parts.tblPr);
282
+ const style = tableStyleFor(styleId, context);
250
283
  const tableFormat = layerTableFormat(
251
284
  style?.table ?? {},
252
285
  readTableFormat(parts.tblPr)
253
286
  );
254
- const lines = {
255
- rows: parts.rows.length,
256
- cols: width,
257
- outer: tableFormat,
258
- inside: layerInsideBorders(
259
- style?.tableInside ?? NO_INSIDE_BORDERS,
260
- readInsideBorders(parts.tblPr)
261
- ),
262
- margins: layerCellMargins(
263
- style?.tableCellMargins ?? NO_CELL_MARGINS,
264
- readCellMarginsOf(parts.tblPr, "tblCellMar")
265
- )
287
+ const bands = layerBandSizes(
288
+ style?.tableBands ?? NO_BAND_SIZES,
289
+ readBandSizes(parts.tblPr)
290
+ );
291
+ const conditions = cellConditionsOf(style?.tableConditions ?? {});
292
+ const table = {
293
+ grid: { rows: parts.rows.length, cols: width },
294
+ sources: {
295
+ outer: tableFormat,
296
+ inside: layerInsideBorders(
297
+ style?.tableInside ?? NO_INSIDE_BORDERS,
298
+ readInsideBorders(parts.tblPr)
299
+ ),
300
+ margins: layerCellMargins(
301
+ style?.tableCellMargins ?? NO_CELL_MARGINS,
302
+ readCellMarginsOf(parts.tblPr, "tblCellMar")
303
+ ),
304
+ look: readTableLook(parts.tblPr),
305
+ bands,
306
+ conditions,
307
+ styleId
308
+ }
266
309
  };
267
310
  const rows = [];
268
311
  for (const [index, row] of parts.rows.entries()) {
269
- const built = buildRow(row, drafts[index], lines, sources);
312
+ const built = buildRow(row, drafts[index], table, sources, context);
270
313
  if (!built) return null;
271
314
  rows.push(built);
272
315
  }
@@ -278,10 +321,8 @@ function buildTable(el, srcId, sources = NO_IMPORT_SOURCES, styles = NO_STYLES,
278
321
  tblW: readTableWidth(parts.tblPr, "tblW"),
279
322
  gridCols,
280
323
  gridChange: parts.gridChange,
281
- format: tableFormat,
282
- // The cells need these again whenever an edit derives their display values afresh
283
- styleInside: toInsideBorders(style?.tableInside),
284
- styleCellMargins: toCellMargins(style?.tableCellMargins)
324
+ leadingXml: parts.leadingXml,
325
+ ...tableStyleAttrs(parts.tblPr, context)
285
326
  },
286
327
  rows
287
328
  );