@portone/docx-editor 0.2.1 → 0.4.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 (253) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/CONTRIBUTING.md +5 -1
  3. package/dist/DocxEditor.d.ts +6 -0
  4. package/dist/DocxEditor.js +13 -29
  5. package/dist/core.d.ts +23 -8
  6. package/dist/core.js +9 -4
  7. package/dist/docx/cloning.d.ts +38 -0
  8. package/dist/docx/cloning.js +74 -0
  9. package/dist/docx/commentOnlyChange.d.ts +12 -7
  10. package/dist/docx/commentOnlyChange.js +9 -156
  11. package/dist/docx/comments/constants.d.ts +0 -1
  12. package/dist/docx/comments/constants.js +0 -2
  13. package/dist/docx/comments/grammar.d.ts +10 -4
  14. package/dist/docx/comments/grammar.js +12 -2
  15. package/dist/docx/comments/{verifying.d.ts → parts.d.ts} +26 -18
  16. package/dist/docx/comments/parts.js +279 -0
  17. package/dist/docx/comments/people.d.ts +11 -2
  18. package/dist/docx/comments/people.js +16 -92
  19. package/dist/docx/comments/policy.d.ts +7 -0
  20. package/dist/docx/comments/policy.js +43 -0
  21. package/dist/docx/comments/reading.js +8 -10
  22. package/dist/docx/comments/writing.d.ts +19 -7
  23. package/dist/docx/comments/writing.js +59 -112
  24. package/dist/docx/documentSettings.d.ts +7 -0
  25. package/dist/docx/documentSettings.js +10 -2
  26. package/dist/docx/exportDocx.d.ts +40 -5
  27. package/dist/docx/exportDocx.js +88 -74
  28. package/dist/docx/exportRefs.d.ts +5 -2
  29. package/dist/docx/exportRefs.js +3 -1
  30. package/dist/docx/fidelity.d.ts +43 -0
  31. package/dist/docx/fidelity.js +64 -0
  32. package/dist/docx/formatting/attrs.d.ts +45 -0
  33. package/dist/docx/formatting/attrs.js +86 -0
  34. package/dist/docx/formatting/context.d.ts +39 -0
  35. package/dist/docx/formatting/context.js +60 -0
  36. package/dist/docx/formatting/direct.d.ts +6 -5
  37. package/dist/docx/formatting/direct.js +52 -78
  38. package/dist/docx/formatting/resolve.d.ts +51 -0
  39. package/dist/docx/formatting/resolve.js +160 -0
  40. package/dist/docx/formatting/runProperties.d.ts +93 -0
  41. package/dist/docx/formatting/runProperties.js +316 -0
  42. package/dist/docx/formatting/styles.d.ts +25 -2
  43. package/dist/docx/formatting/styles.js +87 -6
  44. package/dist/docx/formatting/tabStops.js +7 -22
  45. package/dist/docx/formatting.d.ts +4 -1
  46. package/dist/docx/formatting.js +4 -1
  47. package/dist/docx/headersFooters.js +6 -13
  48. package/dist/docx/hyperlink.d.ts +14 -4
  49. package/dist/docx/hyperlink.js +4 -1
  50. package/dist/docx/identities.d.ts +67 -0
  51. package/dist/docx/identities.js +174 -0
  52. package/dist/docx/importDocx.d.ts +12 -1
  53. package/dist/docx/importDocx.js +90 -88
  54. package/dist/docx/importParagraph.d.ts +1 -1
  55. package/dist/docx/importParagraph.js +4 -3
  56. package/dist/docx/importTable.d.ts +2 -2
  57. package/dist/docx/importTable.js +69 -56
  58. package/dist/docx/invariants.d.ts +33 -0
  59. package/dist/docx/invariants.js +269 -0
  60. package/dist/docx/media.d.ts +6 -4
  61. package/dist/docx/media.js +6 -37
  62. package/dist/docx/newLists.d.ts +50 -0
  63. package/dist/docx/newLists.js +59 -0
  64. package/dist/docx/notes.js +3 -7
  65. package/dist/docx/numberingPlanner.d.ts +11 -0
  66. package/dist/docx/numberingPlanner.js +50 -0
  67. package/dist/docx/packageParts.d.ts +42 -0
  68. package/dist/docx/packageParts.js +135 -0
  69. package/dist/docx/pageGeometry.d.ts +2 -0
  70. package/dist/docx/pageGeometry.js +18 -9
  71. package/dist/docx/paraProps.d.ts +10 -22
  72. package/dist/docx/paraProps.js +47 -76
  73. package/dist/docx/partPlan.d.ts +36 -0
  74. package/dist/docx/partPlan.js +59 -0
  75. package/dist/docx/protectionPolicy.d.ts +127 -0
  76. package/dist/docx/protectionPolicy.js +169 -0
  77. package/dist/docx/relationships.d.ts +1 -1
  78. package/dist/docx/relationships.js +8 -13
  79. package/dist/docx/runProps.d.ts +9 -22
  80. package/dist/docx/runProps.js +15 -168
  81. package/dist/docx/scan.js +20 -52
  82. package/dist/docx/sdt.js +9 -34
  83. package/dist/docx/sdtProps.d.ts +8 -1
  84. package/dist/docx/sdtProps.js +10 -0
  85. package/dist/docx/serializeBlock.d.ts +2 -0
  86. package/dist/docx/serializeBlock.js +8 -5
  87. package/dist/docx/serializeTable.js +32 -15
  88. package/dist/docx/session.d.ts +42 -14
  89. package/dist/docx/session.js +53 -17
  90. package/dist/docx/tableFormatting/conditions.d.ts +76 -0
  91. package/dist/docx/tableFormatting/conditions.js +196 -0
  92. package/dist/docx/tableFormatting/editing.d.ts +7 -3
  93. package/dist/docx/tableFormatting/editing.js +111 -143
  94. package/dist/docx/tableFormatting/reading.d.ts +63 -23
  95. package/dist/docx/tableFormatting/reading.js +132 -38
  96. package/dist/docx/tableFormatting.d.ts +1 -0
  97. package/dist/docx/tableFormatting.js +1 -0
  98. package/dist/docx/tableTemplate.js +30 -19
  99. package/dist/download.d.ts +8 -5
  100. package/dist/download.js +2 -0
  101. package/dist/editor/clipboard/inlineFormatting.js +19 -30
  102. package/dist/editor/commands/comments/editing.d.ts +6 -2
  103. package/dist/editor/commands/comments/editing.js +19 -31
  104. package/dist/editor/commands/exportQueries.d.ts +15 -0
  105. package/dist/editor/commands/exportQueries.js +14 -0
  106. package/dist/editor/commands/fidelityQueries.d.ts +12 -0
  107. package/dist/editor/commands/fidelityQueries.js +8 -0
  108. package/dist/editor/commands/formatting/editing.d.ts +2 -2
  109. package/dist/editor/commands/formatting/editing.js +26 -108
  110. package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
  111. package/dist/editor/commands/formatting/propertyCommands.js +108 -0
  112. package/dist/editor/commands/formatting/shared.d.ts +3 -3
  113. package/dist/editor/commands/formatting/shared.js +5 -2
  114. package/dist/editor/commands/indentCommands.js +5 -4
  115. package/dist/editor/commands/index.d.ts +11 -0
  116. package/dist/editor/commands/index.js +5 -0
  117. package/dist/editor/commands/linkCommands.js +5 -6
  118. package/dist/editor/commands/listCommands.d.ts +6 -3
  119. package/dist/editor/commands/listCommands.js +73 -30
  120. package/dist/editor/commands/lockCommands.d.ts +7 -1
  121. package/dist/editor/commands/lockCommands.js +35 -46
  122. package/dist/editor/commands/paragraphCommands.js +33 -31
  123. package/dist/editor/commands/spacingCommands.js +1 -1
  124. package/dist/editor/createEditor.d.ts +17 -29
  125. package/dist/editor/createEditor.js +58 -58
  126. package/dist/editor/documentStyles.d.ts +11 -35
  127. package/dist/editor/documentStyles.js +9 -52
  128. package/dist/editor/editorDocument.d.ts +57 -0
  129. package/dist/editor/editorDocument.js +86 -0
  130. package/dist/editor/externalClipboard.d.ts +13 -2
  131. package/dist/editor/externalClipboard.js +76 -75
  132. package/dist/editor/insertTable.js +4 -3
  133. package/dist/editor/paragraphEdits.d.ts +27 -19
  134. package/dist/editor/paragraphEdits.js +18 -19
  135. package/dist/editor/paragraphPlacement.d.ts +11 -0
  136. package/dist/editor/paragraphPlacement.js +18 -0
  137. package/dist/editor/plugins/displayDerivation.d.ts +47 -0
  138. package/dist/editor/plugins/displayDerivation.js +78 -0
  139. package/dist/editor/plugins/imagePaste.js +11 -7
  140. package/dist/editor/plugins/keymap.js +18 -3
  141. package/dist/editor/plugins/numberingDecorations.d.ts +14 -14
  142. package/dist/editor/plugins/numberingDecorations.js +50 -19
  143. package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
  144. package/dist/editor/plugins/paragraphDisplay.js +57 -0
  145. package/dist/editor/plugins/tabLayout.js +1 -1
  146. package/dist/editor/plugins/tableDisplay.d.ts +6 -0
  147. package/dist/editor/plugins/tableDisplay.js +30 -0
  148. package/dist/index.d.ts +2 -0
  149. package/dist/model/format.d.ts +80 -8
  150. package/dist/model/format.js +100 -22
  151. package/dist/model/tabStops.d.ts +9 -0
  152. package/dist/model/tabStops.js +18 -0
  153. package/dist/numbering/listRegistry.d.ts +37 -0
  154. package/dist/numbering/listRegistry.js +112 -0
  155. package/dist/numbering/listTemplate.d.ts +26 -17
  156. package/dist/numbering/listTemplate.js +88 -25
  157. package/dist/numbering/markers.d.ts +15 -6
  158. package/dist/numbering/markers.js +26 -59
  159. package/dist/numbering/parseNumbering.d.ts +84 -6
  160. package/dist/numbering/parseNumbering.js +131 -44
  161. package/dist/numbering/spellers.d.ts +15 -0
  162. package/dist/numbering/spellers.js +96 -0
  163. package/dist/numbering/writeNumbering.d.ts +8 -7
  164. package/dist/numbering/writeNumbering.js +28 -39
  165. package/dist/ooxml/childOrder.d.ts +34 -0
  166. package/dist/ooxml/childOrder.js +496 -0
  167. package/dist/ooxml/conformance.d.ts +28 -0
  168. package/dist/ooxml/conformance.js +20 -0
  169. package/dist/ooxml/element.d.ts +24 -11
  170. package/dist/ooxml/element.js +31 -12
  171. package/dist/ooxml/errors.d.ts +6 -5
  172. package/dist/ooxml/image.d.ts +4 -0
  173. package/dist/ooxml/image.js +2 -5
  174. package/dist/ooxml/names.d.ts +9 -0
  175. package/dist/ooxml/names.js +8 -1
  176. package/dist/ooxml/partSplice.d.ts +67 -0
  177. package/dist/ooxml/partSplice.js +176 -0
  178. package/dist/ooxml/props.d.ts +112 -0
  179. package/dist/{docx/propsXml.js → ooxml/props.js} +72 -200
  180. package/dist/ooxml/simpleTypes.d.ts +103 -0
  181. package/dist/ooxml/simpleTypes.js +182 -0
  182. package/dist/ooxml/tabStops.js +8 -27
  183. package/dist/ooxml/tagScan.d.ts +34 -0
  184. package/dist/ooxml/tagScan.js +108 -0
  185. package/dist/ooxml/units.d.ts +25 -13
  186. package/dist/ooxml/units.js +65 -31
  187. package/dist/ooxml/xml.d.ts +35 -15
  188. package/dist/ooxml/xml.js +43 -11
  189. package/dist/page/PageGuides.d.ts +1 -1
  190. package/dist/page/PageGuides.js +0 -13
  191. package/dist/page/blockKinds.d.ts +61 -0
  192. package/dist/page/blockKinds.js +11 -0
  193. package/dist/page/kinds/index.d.ts +6 -0
  194. package/dist/page/kinds/index.js +10 -0
  195. package/dist/page/kinds/paragraphKind.d.ts +10 -0
  196. package/dist/page/kinds/paragraphKind.js +71 -0
  197. package/dist/page/kinds/tableKind.d.ts +10 -0
  198. package/dist/page/kinds/tableKind.js +178 -0
  199. package/dist/page/measureBlocks.d.ts +3 -14
  200. package/dist/page/measureBlocks.js +24 -45
  201. package/dist/page/pageDecorations.d.ts +27 -44
  202. package/dist/page/pageDecorations.js +70 -152
  203. package/dist/page/pageLayout.d.ts +2 -29
  204. package/dist/page/pageLayout.js +39 -16
  205. package/dist/page/usePageLayout.d.ts +2 -24
  206. package/dist/page/usePageLayout.js +5 -48
  207. package/dist/schema/attrRoles.d.ts +25 -18
  208. package/dist/schema/attrRoles.js +110 -68
  209. package/dist/schema/displayDerivation.d.ts +82 -0
  210. package/dist/schema/displayDerivation.js +130 -0
  211. package/dist/schema/docxSchema.d.ts +3 -0
  212. package/dist/schema/docxSchema.js +58 -17
  213. package/dist/schema/editGuard.d.ts +1 -1
  214. package/dist/schema/guards.d.ts +37 -14
  215. package/dist/schema/guards.js +29 -3
  216. package/dist/schema/index.d.ts +2 -0
  217. package/dist/schema/index.js +2 -0
  218. package/dist/schema/locks.d.ts +11 -44
  219. package/dist/schema/locks.js +0 -9
  220. package/dist/schema/preservedGuards.d.ts +26 -6
  221. package/dist/schema/preservedGuards.js +31 -1
  222. package/dist/schema/protection.d.ts +7 -1
  223. package/dist/schema/protection.js +2 -1
  224. package/dist/schema/sourceEquality.d.ts +1 -9
  225. package/dist/schema/sourceEquality.js +1 -27
  226. package/dist/styles/classNames.d.ts +13 -2
  227. package/dist/styles/classNames.js +13 -2
  228. package/dist/styles/inlineStyle.js +15 -6
  229. package/dist/styles.css +16 -18
  230. package/dist/table/cellFormatting.d.ts +8 -1
  231. package/dist/table/cellFormatting.js +11 -20
  232. package/dist/table/commands.js +20 -18
  233. package/dist/table/format.d.ts +3 -0
  234. package/dist/table/format.js +3 -9
  235. package/dist/table/gridBorders.d.ts +24 -30
  236. package/dist/table/gridBorders.js +35 -59
  237. package/dist/table/merge.d.ts +2 -6
  238. package/dist/table/merge.js +5 -5
  239. package/package.json +7 -3
  240. package/dist/docx/comments/contentTypes.d.ts +0 -7
  241. package/dist/docx/comments/contentTypes.js +0 -38
  242. package/dist/docx/comments/verifying.js +0 -206
  243. package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
  244. package/dist/docx/formatting/effectiveParagraph.js +0 -81
  245. package/dist/docx/propsXml.d.ts +0 -67
  246. package/dist/docx/uniqueControls.d.ts +0 -14
  247. package/dist/docx/uniqueControls.js +0 -62
  248. package/dist/editor/plugins/commentReservations.d.ts +0 -5
  249. package/dist/editor/plugins/commentReservations.js +0 -26
  250. package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
  251. package/dist/editor/plugins/styledParagraphs.js +0 -65
  252. package/dist/page/tableMeasurements.d.ts +0 -18
  253. package/dist/page/tableMeasurements.js +0 -119
@@ -3,29 +3,20 @@ import {
3
3
  TextSelection
4
4
  } from "prosemirror-state";
5
5
  import { namesNothing, newControlId } from "../../docx/sdt.js";
6
- import { withContentLock } from "../../docx/sdtProps.js";
7
- import { elementXml, openTagXml } from "../../ooxml/element.js";
8
- import { wName } from "../../ooxml/names.js";
6
+ import { lockedControlPrefix, withContentLock } from "../../docx/sdtProps.js";
9
7
  import { docxSchema } from "../../schema/index.js";
8
+ import { guardedCommand, openStretches } from "../../schema/guards.js";
10
9
  import {
11
10
  carriesLock,
12
11
  controlSpans,
13
12
  isLockedCell,
14
- rangeTouchesLocked,
15
13
  selectionShut,
16
14
  unlockAllowed
17
15
  } from "../../schema/locks.js";
18
16
  import { editsShut } from "../../schema/protectionState.js";
19
17
  function lockedControlMark(id) {
20
18
  return docxSchema.marks.sdt.create({
21
- sdtPrefix: openTagXml(wName("sdt"), null) + elementXml(
22
- wName("sdtPr"),
23
- [],
24
- [
25
- elementXml(wName("id"), [[wName("val"), `${id}`]]),
26
- elementXml(wName("lock"), [[wName("val"), "sdtContentLocked"]])
27
- ]
28
- ),
19
+ sdtPrefix: lockedControlPrefix(id),
29
20
  contentsLocked: true,
30
21
  deletionLocked: true
31
22
  });
@@ -76,29 +67,33 @@ function takeover(met, stretch, open) {
76
67
  if (!only || isLocked(only.mark) || !prefix || !namesNothing(prefix)) {
77
68
  return null;
78
69
  }
79
- const mark = open(stretch) ? withLock(only.mark, true) : null;
70
+ const mark = open ? withLock(only.mark, true) : null;
80
71
  return mark ? {
81
72
  from: Math.min(stretch.from, only.from),
82
73
  to: Math.max(stretch.to, only.to),
83
74
  mark
84
75
  } : null;
85
76
  }
86
- function blockLockEdits(doc, block, spans, reach) {
77
+ function blockLockEdits(state, block, spans, reach) {
87
78
  const stretch = stretchIn(block, reach);
88
79
  if (!stretch) return [];
89
- const open = (at) => !rangeTouchesLocked(doc, at.from, at.to);
80
+ const open = (of) => openStretches(state, of, "mark");
90
81
  const met = spans.filter((span) => overlaps(span, stretch));
91
- const taken = takeover(met, stretch, open);
82
+ const taken = takeover(met, stretch, open([stretch]).length > 0);
92
83
  if (taken) return [taken];
93
- const shut = met.filter((span) => !isLocked(span.mark) && open(span)).flatMap((span) => {
94
- const mark = withLock(span.mark, true);
95
- return mark ? [{ from: span.from, to: span.to, mark }] : [];
96
- });
97
- const fresh = gapsIn(stretch, spans).filter(open).map((gap) => ({ ...gap, mark: lockedControlMark(newControlId()) }));
84
+ const shut = open(met.filter((span) => !isLocked(span.mark))).flatMap(
85
+ (span) => {
86
+ const mark = withLock(span.mark, true);
87
+ return mark ? [{ from: span.from, to: span.to, mark }] : [];
88
+ }
89
+ );
90
+ const fresh = open(gapsIn(stretch, spans)).map((gap) => ({
91
+ ...gap,
92
+ mark: lockedControlMark(newControlId())
93
+ }));
98
94
  return [...shut, ...fresh];
99
95
  }
100
96
  function selectionLockDetail(state) {
101
- if (editsShut(state)) return { kind: "none" };
102
97
  const selection = state.selection;
103
98
  const locking = !selection.empty && selection instanceof TextSelection;
104
99
  const edits = [];
@@ -115,7 +110,7 @@ function selectionLockDetail(state) {
115
110
  if (isLocked(span.mark) && reaches(span, reach)) spans.push(span);
116
111
  }
117
112
  if (locking) {
118
- edits.push(...blockLockEdits(state.doc, block, controls, reach));
113
+ edits.push(...blockLockEdits(state, block, controls, reach));
119
114
  }
120
115
  return false;
121
116
  });
@@ -131,7 +126,7 @@ function selectionLockDetail(state) {
131
126
  return anyLocked ? { kind: "mixed", edits, ...locked } : { kind: "lockable", edits };
132
127
  }
133
128
  function selectionLock(state) {
134
- return selectionLockDetail(state).kind;
129
+ return editsShut(state) ? "none" : selectionLockDetail(state).kind;
135
130
  }
136
131
  function lockEditsOf(lock) {
137
132
  switch (lock.kind) {
@@ -154,16 +149,13 @@ function lockedOf(lock) {
154
149
  return NOTHING_LOCKED;
155
150
  }
156
151
  }
157
- var lockSelection = (state, dispatch) => {
152
+ var lockSelection = guardedCommand((state) => {
158
153
  const edits = lockEditsOf(selectionLockDetail(state));
159
- if (edits.length === 0) return false;
160
- if (dispatch) {
161
- const tr = state.tr;
162
- for (const edit of edits) tr.addMark(edit.from, edit.to, edit.mark);
163
- dispatch(tr);
164
- }
165
- return true;
166
- };
154
+ if (edits.length === 0) return null;
155
+ const tr = state.tr;
156
+ for (const edit of edits) tr.addMark(edit.from, edit.to, edit.mark);
157
+ return tr;
158
+ });
167
159
  function unlockCell(tr, cell) {
168
160
  const prefix = prefixOf(cell.node.attrs);
169
161
  tr.setNodeMarkup(cell.pos, null, {
@@ -173,21 +165,18 @@ function unlockCell(tr, cell) {
173
165
  sdtDeletionLocked: false
174
166
  });
175
167
  }
176
- var unlockSelection = (state, dispatch) => {
168
+ var unlockSelection = guardedCommand((state) => {
177
169
  const { spans, cells } = lockedOf(selectionLockDetail(state));
178
- if (spans.length === 0 && cells.length === 0) return false;
179
- if (dispatch) {
180
- const tr = state.tr.setMeta(unlockAllowed, true);
181
- for (const span of spans) {
182
- const opened = withLock(span.mark, false);
183
- if (opened) tr.addMark(span.from, span.to, opened);
184
- else tr.removeMark(span.from, span.to, span.mark);
185
- }
186
- for (const cell of cells) unlockCell(tr, cell);
187
- dispatch(tr);
170
+ if (spans.length === 0 && cells.length === 0) return null;
171
+ const tr = state.tr.setMeta(unlockAllowed, true);
172
+ for (const span of spans) {
173
+ const opened = withLock(span.mark, false);
174
+ if (opened) tr.addMark(span.from, span.to, opened);
175
+ else tr.removeMark(span.from, span.to, span.mark);
188
176
  }
189
- return true;
190
- };
177
+ for (const cell of cells) unlockCell(tr, cell);
178
+ return tr;
179
+ });
191
180
  function selectionTouchesLocked(state) {
192
181
  return selectionShut(state.selection, state.doc);
193
182
  }
@@ -1,22 +1,25 @@
1
1
  // src/editor/commands/paragraphCommands.ts
2
- import { layerRunFormat, styleIdOf } from "../../docx/formatting.js";
2
+ import {
3
+ paragraphAttrsOf,
4
+ resolveParagraph,
5
+ runMarkUnder,
6
+ styleIdOf
7
+ } from "../../docx/formatting.js";
3
8
  import {
4
9
  withParagraphAlign,
5
10
  withParagraphStyle
6
11
  } from "../../docx/paraProps.js";
7
- import { readRunProps } from "../../docx/runProps.js";
8
- import {
9
- toParagraphFormat
10
- } from "../../model/format.js";
12
+ import { toParagraphFormat } from "../../model/format.js";
11
13
  import { docxSchema } from "../../schema/index.js";
12
14
  import { lockedMarkOf } from "../../schema/locks.js";
13
- import { defaultParagraphStyleId, documentStyles } from "../documentStyles.js";
15
+ import { documentFormatting } from "../documentStyles.js";
14
16
  import {
15
17
  editableParagraphs,
16
18
  editParagraphs,
17
19
  paragraphPPr,
18
20
  selectedParagraphs
19
21
  } from "../paragraphEdits.js";
22
+ import { paragraphPlacementAt } from "../paragraphPlacement.js";
20
23
  function alignOf(node) {
21
24
  return toParagraphFormat(node.attrs.format)?.align ?? "left";
22
25
  }
@@ -24,9 +27,9 @@ function setParagraphAlign(align) {
24
27
  return (state, dispatch) => editParagraphs(
25
28
  state,
26
29
  dispatch,
27
- (node, styles, defaultStyleId) => (
30
+ (node) => (
28
31
  // A paragraph already rendered with that alignment is left untouched, so its original XML survives
29
- alignOf(node) === align ? null : withParagraphAlign(paragraphPPr(node), align, styles, defaultStyleId)
32
+ alignOf(node) === align ? null : withParagraphAlign(paragraphPPr(node), align)
30
33
  )
31
34
  );
32
35
  }
@@ -38,25 +41,16 @@ function activeParagraphAlign(state) {
38
41
  const first = aligns[0];
39
42
  return first !== void 0 && aligns.every((align) => align === first) ? { kind: "shared", align: first } : { kind: "mixed" };
40
43
  }
41
- function text(value) {
42
- return typeof value === "string" ? value : null;
43
- }
44
- function restyledMark(child, style) {
45
- const mark = child.marks.find((entry) => entry.type === docxSchema.marks.run);
46
- if (mark) {
47
- const format2 = layerRunFormat(style, readRunProps(text(mark.attrs.rPr)));
48
- return mark.type.create({ ...mark.attrs, format: format2 });
49
- }
50
- if (!child.isText) return null;
51
- const format = layerRunFormat(style, null);
52
- if (format === null) return null;
53
- return docxSchema.marks.run.create({ rPr: null, rAttrs: null, format });
54
- }
55
- function restyledMarks(spot, style) {
44
+ function restyledMarks(spot, paragraph, context) {
56
45
  const changes = [];
57
46
  spot.node.forEach((child, offset) => {
58
47
  if (lockedMarkOf(child)) return;
59
- const mark = restyledMark(child, style);
48
+ const mark = runMarkUnder(
49
+ child.marks.find((entry) => entry.type === docxSchema.marks.run) ?? null,
50
+ child.isText,
51
+ paragraph,
52
+ context
53
+ );
60
54
  if (!mark) return;
61
55
  const from = spot.pos + 1 + offset;
62
56
  changes.push({ from, to: from + child.nodeSize, mark });
@@ -65,12 +59,11 @@ function restyledMarks(spot, style) {
65
59
  }
66
60
  function writeStyleChanges(state, changed) {
67
61
  const tr = state.tr;
68
- for (const { spot, props, marks } of changed) {
62
+ for (const { spot, props, attrs, marks } of changed) {
69
63
  tr.setNodeMarkup(tr.mapping.map(spot.pos), void 0, {
70
64
  ...spot.node.attrs,
71
65
  pPr: props.pPr,
72
- format: props.format,
73
- styleRun: props.styleRun
66
+ ...attrs
74
67
  });
75
68
  for (const change of marks) {
76
69
  tr.addMark(change.from, change.to, change.mark);
@@ -80,15 +73,24 @@ function writeStyleChanges(state, changed) {
80
73
  }
81
74
  function setParagraphStyle(styleId) {
82
75
  return (state, dispatch) => {
83
- const styles = documentStyles(state);
84
- const defaultStyleId = defaultParagraphStyleId(state);
76
+ const context = documentFormatting(state);
85
77
  const changed = editableParagraphs(state).flatMap((spot) => {
86
78
  const pPr = paragraphPPr(spot.node);
87
79
  if (styleIdOf(pPr) === styleId) return [];
88
- const props = withParagraphStyle(pPr, styleId, styles, defaultStyleId);
80
+ const props = withParagraphStyle(pPr, styleId);
89
81
  if (!props) return [];
82
+ const paragraph = resolveParagraph(
83
+ props.pPr,
84
+ context,
85
+ paragraphPlacementAt(state.doc, spot.pos)
86
+ );
90
87
  return [
91
- { spot, props, marks: restyledMarks(spot, props.styleRun ?? {}) }
88
+ {
89
+ spot,
90
+ props,
91
+ attrs: paragraphAttrsOf(paragraph),
92
+ marks: restyledMarks(spot, paragraph, context)
93
+ }
92
94
  ];
93
95
  });
94
96
  if (changed.length === 0) return false;
@@ -24,7 +24,7 @@ function setLineSpacing(spacing) {
24
24
  return editParagraphs(
25
25
  state,
26
26
  dispatch,
27
- (node, styles, defaultStyleId) => sameLineSpacing(lineSpacingOf(node, defaults), spacing) ? null : withLineSpacing(paragraphPPr(node), spacing, styles, defaultStyleId)
27
+ (node) => sameLineSpacing(lineSpacingOf(node, defaults), spacing) ? null : withLineSpacing(paragraphPPr(node), spacing)
28
28
  );
29
29
  };
30
30
  }
@@ -4,42 +4,25 @@
4
4
  import type { Node as PMNode } from "prosemirror-model";
5
5
  import { EditorState, type Plugin } from "prosemirror-state";
6
6
  import { EditorView } from "prosemirror-view";
7
- import { type ParagraphFormatLayer, type ParagraphStyleOption, type StyleTable } from "../docx/formatting";
8
- import { type PageGeometry } from "../docx/pageGeometry";
9
- import type { DocumentDefaults } from "../model/format";
10
- import { type Numbering } from "../numbering/parseNumbering";
7
+ import type { SessionStore } from "../docx/session";
11
8
  import type { EditableComments, EditingProtection } from "../schema/protection";
12
9
  import { type FontFallbacks } from "../styles/fontStack";
13
10
  import type { CommentAuthor } from "./commands/comments/model";
11
+ import { type EditorDocument } from "./editorDocument";
14
12
  export interface EditorStateOptions {
15
- numbering?: Numbering;
16
- styles?: StyleTable;
17
- defaults?: DocumentDefaults;
18
- /** Paragraph properties from styles.xml docDefaults. */
19
- paragraphDefaults?: ParagraphFormatLayer;
20
13
  /**
21
- * Whether the document has a place (numbering.xml) to write the definition of a new list.
22
- * Callers that build a state without opening a document assume that place exists and behave
23
- * as they do today.
14
+ * What the opened document laid down: its styles, its list definitions, the paper it is
15
+ * written on. A state built without one reads `NO_DOCUMENT`, which answers as nothing having
16
+ * been written down. `editorStateForSession` is what fills it in for an opened document.
24
17
  */
25
- canStartNewList?: boolean;
18
+ document?: EditorDocument;
26
19
  /** The plugins handed in from outside the package */
27
20
  consumerPlugins?: readonly Plugin[];
28
- /** The styles the document defines for the style picker to offer */
29
- paragraphStyles?: ParagraphStyleOption[];
30
21
  /**
31
22
  * Whether the right click is the editor's own. Turned off, the browser's own menu is never
32
23
  * taken away, which is what a consumer drawing menus of its own needs.
33
24
  */
34
25
  contextMenus?: boolean;
35
- /** The paper the document names. A4 where a document names none */
36
- geometry?: PageGeometry;
37
- /** The interval between automatic tab stops, in points. */
38
- defaultTabStopPt?: number;
39
- /** Every id already present in the opened Comments part, including unreferenced entries. */
40
- reservedCommentIds?: Iterable<string>;
41
- /** Every paragraph id present in the opened comment parts, including orphan extension entries. */
42
- reservedCommentParaIds?: Iterable<string>;
43
26
  /**
44
27
  * What the document as a whole may receive (`schema/protection`): everything, comments alone,
45
28
  * or nothing. Everything when none is given, which is what every state was before.
@@ -53,17 +36,22 @@ export interface EditorStateOptions {
53
36
  /**
54
37
  * Creates a single editing state.
55
38
  * The list definitions, the style table, and the document defaults are what the document
56
- * wrote down, and commands and the toolbar read them through plugins.
39
+ * wrote down, and commands and the toolbar read them off the snapshot the state holds.
57
40
  */
58
- export declare function createEditorState(doc: PMNode, { numbering, styles, defaults, paragraphDefaults, canStartNewList, consumerPlugins, paragraphStyles, contextMenus, geometry, defaultTabStopPt, reservedCommentIds, reservedCommentParaIds, protection, author, editableComments, }?: EditorStateOptions): EditorState;
41
+ export declare function createEditorState(doc: PMNode, options?: EditorStateOptions): EditorState;
42
+ /**
43
+ * The state for a document that was opened, which is the one way a session becomes an editing
44
+ * state: what the screen builds and what a test builds are then the same values.
45
+ */
46
+ export declare function editorStateForSession(opened: {
47
+ doc: PMNode;
48
+ session: SessionStore;
49
+ }, options?: Omit<EditorStateOptions, "document">): EditorState;
59
50
  export interface EditorOptions {
60
51
  mount: HTMLElement;
61
52
  state: EditorState;
62
- defaults: DocumentDefaults;
63
- /** The paper the document names. The sheet is drawn from it, A4 where a document names none */
64
- geometry?: PageGeometry;
65
53
  /** The fonts stood in for the ones the document declares. The built-in set when none is given */
66
54
  fontFallbacks?: FontFallbacks;
67
55
  onStateChange: (state: EditorState) => void;
68
56
  }
69
- export declare function createEditorView({ mount, state, defaults, geometry, fontFallbacks, onStateChange, }: EditorOptions): EditorView;
57
+ export declare function createEditorView({ mount, state, fontFallbacks, onStateChange, }: EditorOptions): EditorView;
@@ -6,13 +6,6 @@ import { keymap } from "prosemirror-keymap";
6
6
  import { EditorState } from "prosemirror-state";
7
7
  import { tableEditing } from "prosemirror-tables";
8
8
  import { EditorView } from "prosemirror-view";
9
- import { DEFAULT_TAB_STOP_PT } from "../docx/documentSettings.js";
10
- import {
11
- NO_DOCUMENT_DEFAULTS,
12
- NO_STYLES
13
- } from "../docx/formatting.js";
14
- import { A4_PORTRAIT } from "../docx/pageGeometry.js";
15
- import { EMPTY_NUMBERING } from "../numbering/parseNumbering.js";
16
9
  import { pageDecorations } from "../page/pageDecorations.js";
17
10
  import { pageGeometryStyle, pagePixels } from "../page/pageLayout.js";
18
11
  import { editsShut } from "../schema/protectionState.js";
@@ -21,13 +14,20 @@ import {
21
14
  DEFAULT_FONT_FALLBACKS
22
15
  } from "../styles/fontStack.js";
23
16
  import { documentDefaultsStyle } from "../styles/inlineStyle.js";
24
- import { gridBorders, withDerivedGridBorders } from "../table/gridBorders.js";
25
- import { documentDefaultTabStopPt, documentStyleTable } from "./documentStyles.js";
17
+ import {
18
+ documentOf,
19
+ editorDocument,
20
+ editorDocumentOf,
21
+ NO_DOCUMENT
22
+ } from "./editorDocument.js";
26
23
  import { externalClipboard } from "./externalClipboard.js";
27
24
  import { imageFiles } from "./imageFiles.js";
28
25
  import { columnResize } from "./plugins/columnResize.js";
29
26
  import { commentDecorations } from "./plugins/commentDecorations.js";
30
- import { commentReservations } from "./plugins/commentReservations.js";
27
+ import {
28
+ displayDerivation,
29
+ withDerivedDisplay
30
+ } from "./plugins/displayDerivation.js";
31
31
  import { documentProtection } from "./plugins/documentProtection.js";
32
32
  import { imagePaste } from "./plugins/imagePaste.js";
33
33
  import { docxKeymap, historyKeys } from "./plugins/keymap.js";
@@ -36,7 +36,6 @@ import { listInputRules } from "./plugins/listInputRules.js";
36
36
  import { lockedContent } from "./plugins/lockedContent.js";
37
37
  import { numberingMarkers } from "./plugins/numberingDecorations.js";
38
38
  import { rowResize } from "./plugins/rowResize.js";
39
- import { styledParagraphs } from "./plugins/styledParagraphs.js";
40
39
  import { tabCaret } from "./plugins/tabCaret.js";
41
40
  import { tabDecorations } from "./plugins/tabDecorations.js";
42
41
  import { tabLayout } from "./plugins/tabLayout.js";
@@ -45,37 +44,32 @@ import { tabPointer } from "./plugins/tabPointer.js";
45
44
  import { textContextMenu } from "./plugins/textContextMenu.js";
46
45
  import { ImageNodeView } from "./views/imageResize.js";
47
46
  import { runMarkView } from "./views/runMarkView.js";
48
- function createEditorState(doc, {
49
- numbering = EMPTY_NUMBERING,
50
- styles = NO_STYLES,
51
- defaults = NO_DOCUMENT_DEFAULTS,
52
- paragraphDefaults = {},
53
- canStartNewList = true,
54
- consumerPlugins = [],
55
- paragraphStyles = [],
56
- contextMenus = true,
57
- geometry = A4_PORTRAIT,
58
- defaultTabStopPt = DEFAULT_TAB_STOP_PT,
59
- reservedCommentIds = [],
60
- reservedCommentParaIds = [],
61
- protection = "none",
62
- author = null,
63
- editableComments = "own"
64
- } = {}) {
47
+ function createEditorState(doc, options = {}) {
48
+ const {
49
+ document = NO_DOCUMENT,
50
+ consumerPlugins = [],
51
+ contextMenus = true,
52
+ protection = "none",
53
+ author = null,
54
+ editableComments = "own"
55
+ } = options;
65
56
  return EditorState.create({
66
- doc: withDerivedGridBorders(doc),
57
+ // The values the document arrived with were worked out against whatever opened it; the
58
+ // state's are worked out against its own snapshot, tables' shared lines included
59
+ doc: withDerivedDisplay(doc, document),
67
60
  plugins: [
68
61
  // Consumer plugins lead the array. ProseMirror walks the plugins in order and takes the
69
62
  // first answer for a keypress, a paste, a drop or any other DOM event, so this is the
70
63
  // only place from which a consumer handler can win over the built-in one.
71
64
  ...consumerPlugins,
65
+ // Every document-level value the editor reads stands in one snapshot, and it leads the
66
+ // built-in plugins so that the ones drawing from it are initialized after it
67
+ editorDocument(document),
72
68
  // Refuses every edit no guard in `schema/guards` lets through, whoever asked for it. It is
73
69
  // not optional: a document that locked a part of itself stays locked in every consumer, and
74
70
  // the preserved bookmark markers and note references stay where the file put them.
75
71
  lockedContent(),
76
72
  documentProtection({ protection, author, editableComments }),
77
- // An orphan Comments-part entry still owns its id and must not be replaced by a new comment.
78
- commentReservations(reservedCommentIds, reservedCommentParaIds),
79
73
  history(),
80
74
  keymap(docxKeymap),
81
75
  historyKeys(),
@@ -102,52 +96,57 @@ function createEditorState(doc, {
102
96
  tabPointer(),
103
97
  tabLayout(),
104
98
  tabCaret(),
105
- // Keeps table-cell lines aligned with OOXML precedence after an edit
106
- gridBorders(),
107
- // Reads the document's styles into the paragraphs an edit built from nothing
108
- styledParagraphs(),
99
+ // Works the display values out again after every edit: the lines of a table's cells, and
100
+ // the style values of the paragraphs the edit built or rewrote
101
+ displayDerivation(),
109
102
  // Receiving a right-click means taking the browser's own menu away, so both of these stand
110
103
  // or fall together with the menus the editor draws. The text menu stands ahead of the table
111
104
  // menu, and hands a click with nothing selected inside a cell back to it
112
105
  ...contextMenus ? [textContextMenu(), tableContextMenu()] : [],
113
- numberingMarkers(numbering, canStartNewList),
106
+ numberingMarkers(),
114
107
  // Values only go in when page display is turned on
115
- pageDecorations(),
116
- documentStyleTable(
117
- styles,
118
- defaults,
119
- paragraphStyles,
120
- geometry,
121
- paragraphDefaults,
122
- numbering,
123
- defaultTabStopPt
124
- )
108
+ pageDecorations()
125
109
  ]
126
110
  });
127
111
  }
112
+ function editorStateForSession(opened, options = {}) {
113
+ return createEditorState(opened.doc, {
114
+ ...options,
115
+ document: editorDocumentOf(opened.session, opened.doc)
116
+ });
117
+ }
118
+ var sheetStyles = /* @__PURE__ */ new WeakMap();
119
+ function sheetStyleOf(document, fallbacks) {
120
+ const remembered = sheetStyles.get(document);
121
+ if (remembered?.fallbacks === fallbacks) return remembered.style;
122
+ const style = `${pageGeometryStyle(pagePixels(document.geometry))};${documentDefaultsStyle(document.defaults, fallbacks)};`;
123
+ sheetStyles.set(document, { fallbacks, style });
124
+ return style;
125
+ }
128
126
  function createEditorView({
129
127
  mount,
130
128
  state,
131
- defaults,
132
- geometry = A4_PORTRAIT,
133
129
  fontFallbacks = DEFAULT_FONT_FALLBACKS,
134
130
  onStateChange
135
131
  }) {
136
- const sheetStyle = `${pageGeometryStyle(pagePixels(geometry))};${documentDefaultsStyle(defaults, fontFallbacks)};`;
137
132
  const view = new EditorView(mount, {
138
133
  state,
139
134
  // A protection that shuts the body shuts typing with it, and is read off the state so that a
140
135
  // mode switched on an open document takes effect without a new view. Selecting stays open
141
136
  // either way, which is what a reader marking a stretch for a comment needs
142
137
  editable: (current) => !editsShut(current),
143
- attributes: (current) => ({
144
- class: editorClassNames.sheet,
145
- // The paper first, so a document that names one is drawn on it from the first frame
146
- style: `${sheetStyle}tab-size:${documentDefaultTabStopPt(current)}pt`,
147
- // A sheet that takes no typing is no longer focusable of itself, so a reader or a commenter
148
- // is handed the focus another way: the keys reach it, and the selection stays its own
149
- ...editsShut(current) ? { tabindex: "0" } : {}
150
- }),
138
+ attributes: (current) => {
139
+ const document = documentOf(current);
140
+ return {
141
+ class: editorClassNames.sheet,
142
+ // The paper first, so a document that names one is drawn on it from the first frame
143
+ style: `${sheetStyleOf(document, fontFallbacks)}tab-size:${document.defaultTabStopPt}pt`,
144
+ // A sheet that takes no typing is no longer focusable of itself, so a reader or a
145
+ // commenter is handed the focus another way: the keys reach it, and the selection stays
146
+ // its own
147
+ ...editsShut(current) ? { tabindex: "0" } : {}
148
+ };
149
+ },
151
150
  // The schema can only draw a run with the default fallback fonts, so this editor draws its own
152
151
  markViews: { run: runMarkView(fontFallbacks) },
153
152
  // An image is drawn by a view of its own, which is what carries the resize handles
@@ -164,5 +163,6 @@ function createEditorView({
164
163
  }
165
164
  export {
166
165
  createEditorState,
167
- createEditorView
166
+ createEditorView,
167
+ editorStateForSession
168
168
  };
@@ -1,45 +1,23 @@
1
1
  /**
2
- * Brings what the document laid down into the editor: what styles.xml told us, and the paper it
3
- * is written on.
2
+ * What the document laid down, as the commands and the toolbar ask for it: what styles.xml told
3
+ * us, and the paper it is written on.
4
4
  *
5
- * Commands and the toolbar know nothing about the session, so this plugin holds all of it on
6
- * their behalf: deriving the display values again after a formatting edit needs the values the
7
- * style laid down, the toolbar needs the size a run is rendered at where nobody wrote a size
8
- * down, and a new table is fitted to the width of the body the paper leaves.
9
- * The values are fixed the moment the document is opened and do not change while editing.
5
+ * Commands and the toolbar know nothing about the session, so they read the snapshot
6
+ * `editor/editorDocument` holds on their behalf: deriving the display values again after a
7
+ * formatting edit needs the context the hierarchy is resolved against, the toolbar needs the size
8
+ * a run is rendered at where nobody wrote a size down, and a new table is fitted to the width of
9
+ * the body the paper leaves.
10
10
  */
11
- import { type EditorState, Plugin } from "prosemirror-state";
12
- import { type ParagraphFormatLayer, type ParagraphFormattingContext, type ParagraphStyleOption, type StyleTable } from "../docx/formatting";
11
+ import type { EditorState } from "prosemirror-state";
12
+ import type { FormattingContext, ParagraphStyleOption } from "../docx/formatting";
13
13
  import { type PageGeometry } from "../docx/pageGeometry";
14
14
  import type { DocumentDefaults } from "../model/format";
15
- import { type Numbering } from "../numbering/parseNumbering";
16
- /** Values that apply to the whole document */
17
- interface DocumentInfo {
18
- styles: StyleTable;
19
- defaults: DocumentDefaults;
20
- paragraphDefaults: ParagraphFormatLayer;
21
- numbering: Numbering;
22
- paragraphStyles: ParagraphStyleOption[];
23
- /** The paper the document is written on, which decides the width a new table is fitted to */
24
- geometry: PageGeometry;
25
- /** The distance between automatic tab stops when no custom stop applies. */
26
- defaultTabStopPt: number;
27
- }
28
- /** This document's style table. Empty when the editor does not know the table */
29
- export declare function documentStyles(state: EditorState): StyleTable;
15
+ /** Everything a paragraph's or a run's display values are resolved against. Empty when the editor does not know the document */
16
+ export declare function documentFormatting(state: EditorState): FormattingContext;
30
17
  /** The default formatting this document wrote down. When the editor does not know it, it is the same as nothing being specified */
31
18
  export declare function documentDefaults(state: EditorState): DocumentDefaults;
32
- /** The values required to resolve the OOXML paragraph-property hierarchy. */
33
- export declare function documentParagraphFormatting(state: EditorState): ParagraphFormattingContext;
34
19
  /** The paragraph styles this document defines. Empty when the editor does not know them */
35
20
  export declare function documentParagraphStyles(state: EditorState): ParagraphStyleOption[];
36
- /**
37
- * The style a paragraph pointing at none of its own wears (`w:default="1"`). Null when the
38
- * document marks none.
39
- *
40
- * It is the style the list of them marks, of which `readParagraphStyles` leaves exactly one.
41
- */
42
- export declare function defaultParagraphStyleId(state: EditorState): string | null;
43
21
  /**
44
22
  * The paper the document is written on. A document the editor knows no paper for is drawn on
45
23
  * the same A4 every document was drawn on before the geometry was read
@@ -56,5 +34,3 @@ export declare function documentDefaultTabStopPt(state: EditorState): number;
56
34
  export declare function documentBodyWidthPx(state: EditorState): number;
57
35
  /** The height one page of body content occupies, in pixels. */
58
36
  export declare function documentBodyHeightPx(state: EditorState): number;
59
- export declare function documentStyleTable(styles: StyleTable, defaults?: DocumentDefaults, paragraphStyles?: ParagraphStyleOption[], geometry?: PageGeometry, paragraphDefaults?: ParagraphFormatLayer, numbering?: Numbering, defaultTabStopPt?: number): Plugin<DocumentInfo>;
60
- export {};