@portone/docx-editor 0.2.1 → 0.3.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 (225) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/CONTRIBUTING.md +5 -1
  3. package/dist/DocxEditor.d.ts +6 -0
  4. package/dist/DocxEditor.js +12 -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 +52 -111
  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 +69 -71
  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 +27 -0
  33. package/dist/docx/formatting/attrs.js +31 -0
  34. package/dist/docx/formatting/context.d.ts +31 -0
  35. package/dist/docx/formatting/context.js +42 -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 +45 -0
  39. package/dist/docx/formatting/resolve.js +140 -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.js +3 -3
  43. package/dist/docx/formatting/tabStops.js +7 -22
  44. package/dist/docx/formatting.d.ts +4 -1
  45. package/dist/docx/formatting.js +4 -1
  46. package/dist/docx/headersFooters.js +6 -13
  47. package/dist/docx/identities.d.ts +67 -0
  48. package/dist/docx/identities.js +174 -0
  49. package/dist/docx/importDocx.d.ts +12 -1
  50. package/dist/docx/importDocx.js +72 -79
  51. package/dist/docx/importParagraph.d.ts +1 -1
  52. package/dist/docx/importParagraph.js +4 -3
  53. package/dist/docx/importTable.d.ts +1 -1
  54. package/dist/docx/importTable.js +17 -1
  55. package/dist/docx/invariants.d.ts +33 -0
  56. package/dist/docx/invariants.js +256 -0
  57. package/dist/docx/media.d.ts +6 -4
  58. package/dist/docx/media.js +6 -37
  59. package/dist/docx/newLists.d.ts +20 -0
  60. package/dist/docx/newLists.js +36 -0
  61. package/dist/docx/notes.js +3 -7
  62. package/dist/docx/numberingPlanner.d.ts +8 -0
  63. package/dist/docx/numberingPlanner.js +19 -0
  64. package/dist/docx/packageParts.d.ts +42 -0
  65. package/dist/docx/packageParts.js +135 -0
  66. package/dist/docx/pageGeometry.d.ts +2 -0
  67. package/dist/docx/pageGeometry.js +18 -9
  68. package/dist/docx/paraProps.d.ts +10 -22
  69. package/dist/docx/paraProps.js +47 -76
  70. package/dist/docx/partPlan.d.ts +36 -0
  71. package/dist/docx/partPlan.js +59 -0
  72. package/dist/docx/protectionPolicy.d.ts +127 -0
  73. package/dist/docx/protectionPolicy.js +169 -0
  74. package/dist/docx/relationships.d.ts +1 -1
  75. package/dist/docx/relationships.js +8 -13
  76. package/dist/docx/runProps.d.ts +9 -22
  77. package/dist/docx/runProps.js +15 -168
  78. package/dist/docx/scan.js +20 -52
  79. package/dist/docx/sdt.js +9 -34
  80. package/dist/docx/sdtProps.d.ts +8 -1
  81. package/dist/docx/sdtProps.js +10 -0
  82. package/dist/docx/serializeBlock.d.ts +2 -0
  83. package/dist/docx/serializeBlock.js +8 -5
  84. package/dist/docx/serializeTable.js +32 -15
  85. package/dist/docx/session.d.ts +42 -14
  86. package/dist/docx/session.js +43 -17
  87. package/dist/docx/tableFormatting/editing.js +108 -139
  88. package/dist/docx/tableFormatting/reading.d.ts +16 -6
  89. package/dist/docx/tableFormatting/reading.js +40 -20
  90. package/dist/docx/tableTemplate.js +18 -7
  91. package/dist/download.d.ts +8 -5
  92. package/dist/download.js +2 -0
  93. package/dist/editor/clipboard/inlineFormatting.js +19 -30
  94. package/dist/editor/commands/comments/editing.d.ts +6 -2
  95. package/dist/editor/commands/comments/editing.js +19 -31
  96. package/dist/editor/commands/exportQueries.d.ts +15 -0
  97. package/dist/editor/commands/exportQueries.js +14 -0
  98. package/dist/editor/commands/fidelityQueries.d.ts +12 -0
  99. package/dist/editor/commands/fidelityQueries.js +8 -0
  100. package/dist/editor/commands/formatting/editing.d.ts +2 -2
  101. package/dist/editor/commands/formatting/editing.js +26 -108
  102. package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
  103. package/dist/editor/commands/formatting/propertyCommands.js +103 -0
  104. package/dist/editor/commands/formatting/shared.d.ts +3 -3
  105. package/dist/editor/commands/formatting/shared.js +5 -2
  106. package/dist/editor/commands/indentCommands.js +5 -4
  107. package/dist/editor/commands/index.d.ts +11 -0
  108. package/dist/editor/commands/index.js +5 -0
  109. package/dist/editor/commands/linkCommands.js +5 -6
  110. package/dist/editor/commands/listCommands.js +8 -10
  111. package/dist/editor/commands/lockCommands.d.ts +7 -1
  112. package/dist/editor/commands/lockCommands.js +35 -46
  113. package/dist/editor/commands/paragraphCommands.js +28 -31
  114. package/dist/editor/commands/spacingCommands.js +1 -1
  115. package/dist/editor/createEditor.d.ts +17 -29
  116. package/dist/editor/createEditor.js +58 -58
  117. package/dist/editor/documentStyles.d.ts +11 -35
  118. package/dist/editor/documentStyles.js +9 -52
  119. package/dist/editor/editorDocument.d.ts +56 -0
  120. package/dist/editor/editorDocument.js +74 -0
  121. package/dist/editor/externalClipboard.js +16 -45
  122. package/dist/editor/insertTable.js +4 -3
  123. package/dist/editor/paragraphEdits.d.ts +11 -18
  124. package/dist/editor/paragraphEdits.js +7 -16
  125. package/dist/editor/plugins/displayDerivation.d.ts +47 -0
  126. package/dist/editor/plugins/displayDerivation.js +78 -0
  127. package/dist/editor/plugins/imagePaste.js +4 -3
  128. package/dist/editor/plugins/keymap.js +18 -3
  129. package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
  130. package/dist/editor/plugins/numberingDecorations.js +7 -17
  131. package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
  132. package/dist/editor/plugins/paragraphDisplay.js +51 -0
  133. package/dist/editor/plugins/tabLayout.js +1 -1
  134. package/dist/editor/plugins/tableDisplay.d.ts +6 -0
  135. package/dist/editor/plugins/tableDisplay.js +16 -0
  136. package/dist/index.d.ts +2 -0
  137. package/dist/model/format.d.ts +30 -8
  138. package/dist/model/format.js +35 -22
  139. package/dist/model/tabStops.d.ts +9 -0
  140. package/dist/model/tabStops.js +18 -0
  141. package/dist/numbering/listTemplate.js +24 -7
  142. package/dist/numbering/parseNumbering.d.ts +14 -1
  143. package/dist/numbering/parseNumbering.js +35 -22
  144. package/dist/numbering/writeNumbering.d.ts +3 -4
  145. package/dist/numbering/writeNumbering.js +14 -25
  146. package/dist/ooxml/childOrder.d.ts +34 -0
  147. package/dist/ooxml/childOrder.js +496 -0
  148. package/dist/ooxml/element.d.ts +24 -11
  149. package/dist/ooxml/element.js +31 -12
  150. package/dist/ooxml/errors.d.ts +3 -2
  151. package/dist/ooxml/image.d.ts +4 -0
  152. package/dist/ooxml/image.js +2 -5
  153. package/dist/ooxml/partSplice.d.ts +67 -0
  154. package/dist/ooxml/partSplice.js +169 -0
  155. package/dist/ooxml/props.d.ts +112 -0
  156. package/dist/{docx/propsXml.js → ooxml/props.js} +72 -200
  157. package/dist/ooxml/simpleTypes.d.ts +103 -0
  158. package/dist/ooxml/simpleTypes.js +182 -0
  159. package/dist/ooxml/tabStops.js +8 -27
  160. package/dist/ooxml/tagScan.d.ts +34 -0
  161. package/dist/ooxml/tagScan.js +108 -0
  162. package/dist/ooxml/units.d.ts +25 -13
  163. package/dist/ooxml/units.js +65 -31
  164. package/dist/ooxml/xml.d.ts +27 -6
  165. package/dist/ooxml/xml.js +37 -5
  166. package/dist/page/blockKinds.d.ts +61 -0
  167. package/dist/page/blockKinds.js +11 -0
  168. package/dist/page/kinds/index.d.ts +6 -0
  169. package/dist/page/kinds/index.js +10 -0
  170. package/dist/page/kinds/paragraphKind.d.ts +10 -0
  171. package/dist/page/kinds/paragraphKind.js +71 -0
  172. package/dist/page/kinds/tableKind.d.ts +10 -0
  173. package/dist/page/kinds/tableKind.js +178 -0
  174. package/dist/page/measureBlocks.d.ts +3 -14
  175. package/dist/page/measureBlocks.js +24 -45
  176. package/dist/page/pageDecorations.d.ts +27 -44
  177. package/dist/page/pageDecorations.js +70 -152
  178. package/dist/page/pageLayout.d.ts +2 -19
  179. package/dist/page/pageLayout.js +36 -6
  180. package/dist/page/usePageLayout.d.ts +2 -17
  181. package/dist/page/usePageLayout.js +3 -39
  182. package/dist/schema/attrRoles.d.ts +25 -18
  183. package/dist/schema/attrRoles.js +102 -67
  184. package/dist/schema/displayDerivation.d.ts +82 -0
  185. package/dist/schema/displayDerivation.js +130 -0
  186. package/dist/schema/docxSchema.d.ts +3 -0
  187. package/dist/schema/docxSchema.js +26 -14
  188. package/dist/schema/editGuard.d.ts +1 -1
  189. package/dist/schema/guards.d.ts +37 -14
  190. package/dist/schema/guards.js +29 -3
  191. package/dist/schema/index.d.ts +2 -0
  192. package/dist/schema/index.js +2 -0
  193. package/dist/schema/locks.d.ts +11 -44
  194. package/dist/schema/locks.js +0 -9
  195. package/dist/schema/preservedGuards.d.ts +26 -6
  196. package/dist/schema/preservedGuards.js +31 -1
  197. package/dist/schema/protection.d.ts +7 -1
  198. package/dist/schema/protection.js +2 -1
  199. package/dist/schema/sourceEquality.d.ts +1 -9
  200. package/dist/schema/sourceEquality.js +1 -27
  201. package/dist/styles/inlineStyle.js +15 -6
  202. package/dist/table/cellFormatting.d.ts +8 -1
  203. package/dist/table/cellFormatting.js +10 -18
  204. package/dist/table/commands.js +20 -18
  205. package/dist/table/format.d.ts +3 -0
  206. package/dist/table/format.js +3 -9
  207. package/dist/table/gridBorders.d.ts +14 -16
  208. package/dist/table/gridBorders.js +3 -41
  209. package/dist/table/merge.d.ts +2 -6
  210. package/dist/table/merge.js +5 -5
  211. package/package.json +7 -3
  212. package/dist/docx/comments/contentTypes.d.ts +0 -7
  213. package/dist/docx/comments/contentTypes.js +0 -38
  214. package/dist/docx/comments/verifying.js +0 -206
  215. package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
  216. package/dist/docx/formatting/effectiveParagraph.js +0 -81
  217. package/dist/docx/propsXml.d.ts +0 -67
  218. package/dist/docx/uniqueControls.d.ts +0 -14
  219. package/dist/docx/uniqueControls.js +0 -62
  220. package/dist/editor/plugins/commentReservations.d.ts +0 -5
  221. package/dist/editor/plugins/commentReservations.js +0 -26
  222. package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
  223. package/dist/editor/plugins/styledParagraphs.js +0 -65
  224. package/dist/page/tableMeasurements.d.ts +0 -18
  225. package/dist/page/tableMeasurements.js +0 -119
@@ -29,6 +29,8 @@ import {
29
29
  updateComment,
30
30
  updateCommentReply
31
31
  } from "./commentCommands.js";
32
+ import { canExport, documentExportProblems } from "./exportQueries.js";
33
+ import { documentFidelity } from "./fidelityQueries.js";
32
34
  import {
33
35
  activeFontFamily,
34
36
  activeFontSize,
@@ -111,6 +113,7 @@ export {
111
113
  canAddComment,
112
114
  canDecreaseIndent,
113
115
  canEditComment,
116
+ canExport,
114
117
  canFormatText,
115
118
  canIncreaseIndent,
116
119
  canInsertImage,
@@ -124,6 +127,8 @@ export {
124
127
  documentBodyWidthPx,
125
128
  documentComments,
126
129
  documentDefaults,
130
+ documentExportProblems,
131
+ documentFidelity,
127
132
  documentFontNames,
128
133
  documentHasLocked,
129
134
  documentNotes,
@@ -1,7 +1,6 @@
1
1
  // src/editor/commands/linkCommands.ts
2
2
  import { docxSchema } from "../../schema/index.js";
3
- import { rangeTouchesLocked } from "../../schema/locks.js";
4
- import { editsShut } from "../../schema/protectionState.js";
3
+ import { openStretches } from "../../schema/guards.js";
5
4
  var linkType = docxSchema.marks.link;
6
5
  function text(value) {
7
6
  return typeof value === "string" ? value : null;
@@ -75,10 +74,10 @@ function linkSpansTouching(doc, from, to) {
75
74
  return spans;
76
75
  }
77
76
  function openPieces(state) {
78
- if (editsShut(state)) return [];
79
- const found = state.selection.empty ? caretPieces(state) : selectionPieces(state);
80
- return found.filter(
81
- (piece) => !rangeTouchesLocked(state.doc, piece.from, piece.to)
77
+ return openStretches(
78
+ state,
79
+ state.selection.empty ? caretPieces(state) : selectionPieces(state),
80
+ "mark"
82
81
  );
83
82
  }
84
83
  function caretPieces(state) {
@@ -25,9 +25,9 @@ function listRefOf(node) {
25
25
  return toParagraphFormat(node.attrs.format)?.numbering ?? null;
26
26
  }
27
27
  function changeParagraphs(state, dispatch, plan) {
28
- return editParagraphs(state, dispatch, (node, styles, defaultStyleId) => {
28
+ return editParagraphs(state, dispatch, (node) => {
29
29
  const change = plan(node);
30
- return change && withListNumbering(paragraphPPr(node), change, styles, defaultStyleId);
30
+ return change && withListNumbering(paragraphPPr(node), change);
31
31
  });
32
32
  }
33
33
  function indentForLevel(numbering, node, ref) {
@@ -107,15 +107,13 @@ function isInList(state) {
107
107
  (spot) => listRefOf(spot.node) !== null
108
108
  );
109
109
  }
110
- var leaveListAtLineStart = (state, dispatch) => editParagraphs(state, dispatch, (node, styles, defaultStyleId) => {
110
+ var leaveListAtLineStart = (state, dispatch) => editParagraphs(state, dispatch, (node) => {
111
111
  if (!listRefOf(node)) return null;
112
- const unlisted = withListNumbering(
113
- paragraphPPr(node),
114
- { numbering: null, indent: { kind: "clearHanging" } },
115
- styles,
116
- defaultStyleId
117
- );
118
- return unlisted && withLeftIndent(unlisted.pPr, 0, styles, defaultStyleId);
112
+ const unlisted = withListNumbering(paragraphPPr(node), {
113
+ numbering: null,
114
+ indent: { kind: "clearHanging" }
115
+ });
116
+ return unlisted && withLeftIndent(unlisted.pPr, 0);
119
117
  });
120
118
  var leaveEmptyListItem = (state, dispatch) => {
121
119
  const { empty, $from } = state.selection;
@@ -25,7 +25,13 @@ export declare function selectionLock(state: EditorState): SelectionLock;
25
25
  * A selection that also reaches a lock still locks what that lock leaves open.
26
26
  */
27
27
  export declare const lockSelection: Command;
28
- /** Lifts the lock off every control the selection reaches, over that control's whole stretch */
28
+ /**
29
+ * Lifts the lock off every control the selection reaches, over that control's whole stretch.
30
+ *
31
+ * The transaction carries the pass that lets it reach past the very locks it lifts, which is the
32
+ * one thing the pass is for; every other guard still has its say, so lifting a lock stays shut
33
+ * under a protection that shuts the body (`schema/guards`).
34
+ */
29
35
  export declare const unlockSelection: Command;
30
36
  /**
31
37
  * Whether editing where the selection stands is shut.
@@ -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,16 +1,18 @@
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,
@@ -24,9 +26,9 @@ function setParagraphAlign(align) {
24
26
  return (state, dispatch) => editParagraphs(
25
27
  state,
26
28
  dispatch,
27
- (node, styles, defaultStyleId) => (
29
+ (node) => (
28
30
  // 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)
31
+ alignOf(node) === align ? null : withParagraphAlign(paragraphPPr(node), align)
30
32
  )
31
33
  );
32
34
  }
@@ -38,25 +40,16 @@ function activeParagraphAlign(state) {
38
40
  const first = aligns[0];
39
41
  return first !== void 0 && aligns.every((align) => align === first) ? { kind: "shared", align: first } : { kind: "mixed" };
40
42
  }
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) {
43
+ function restyledMarks(spot, paragraph, context) {
56
44
  const changes = [];
57
45
  spot.node.forEach((child, offset) => {
58
46
  if (lockedMarkOf(child)) return;
59
- const mark = restyledMark(child, style);
47
+ const mark = runMarkUnder(
48
+ child.marks.find((entry) => entry.type === docxSchema.marks.run) ?? null,
49
+ child.isText,
50
+ paragraph,
51
+ context
52
+ );
60
53
  if (!mark) return;
61
54
  const from = spot.pos + 1 + offset;
62
55
  changes.push({ from, to: from + child.nodeSize, mark });
@@ -65,12 +58,11 @@ function restyledMarks(spot, style) {
65
58
  }
66
59
  function writeStyleChanges(state, changed) {
67
60
  const tr = state.tr;
68
- for (const { spot, props, marks } of changed) {
61
+ for (const { spot, props, attrs, marks } of changed) {
69
62
  tr.setNodeMarkup(tr.mapping.map(spot.pos), void 0, {
70
63
  ...spot.node.attrs,
71
64
  pPr: props.pPr,
72
- format: props.format,
73
- styleRun: props.styleRun
65
+ ...attrs
74
66
  });
75
67
  for (const change of marks) {
76
68
  tr.addMark(change.from, change.to, change.mark);
@@ -80,15 +72,20 @@ function writeStyleChanges(state, changed) {
80
72
  }
81
73
  function setParagraphStyle(styleId) {
82
74
  return (state, dispatch) => {
83
- const styles = documentStyles(state);
84
- const defaultStyleId = defaultParagraphStyleId(state);
75
+ const context = documentFormatting(state);
85
76
  const changed = editableParagraphs(state).flatMap((spot) => {
86
77
  const pPr = paragraphPPr(spot.node);
87
78
  if (styleIdOf(pPr) === styleId) return [];
88
- const props = withParagraphStyle(pPr, styleId, styles, defaultStyleId);
79
+ const props = withParagraphStyle(pPr, styleId);
89
80
  if (!props) return [];
81
+ const paragraph = resolveParagraph(props.pPr, context);
90
82
  return [
91
- { spot, props, marks: restyledMarks(spot, props.styleRun ?? {}) }
83
+ {
84
+ spot,
85
+ props,
86
+ attrs: paragraphAttrsOf(paragraph),
87
+ marks: restyledMarks(spot, paragraph, context)
88
+ }
92
89
  ];
93
90
  });
94
91
  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)
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
  };