@portone/docx-editor 0.2.0 → 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 (256) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/CONTRIBUTING.md +9 -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 +14 -7
  10. package/dist/docx/commentOnlyChange.js +9 -139
  11. package/dist/docx/comments/constants.d.ts +3 -4
  12. package/dist/docx/comments/constants.js +4 -5
  13. package/dist/docx/comments/grammar.d.ts +86 -0
  14. package/dist/docx/comments/grammar.js +223 -0
  15. package/dist/docx/comments/parts.d.ts +52 -0
  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 +28 -106
  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.d.ts +5 -3
  22. package/dist/docx/comments/reading.js +30 -29
  23. package/dist/docx/comments/writing.d.ts +19 -7
  24. package/dist/docx/comments/writing.js +105 -137
  25. package/dist/docx/documentSettings.d.ts +7 -0
  26. package/dist/docx/documentSettings.js +10 -2
  27. package/dist/docx/exportDocx.d.ts +40 -5
  28. package/dist/docx/exportDocx.js +71 -72
  29. package/dist/docx/exportRefs.d.ts +5 -2
  30. package/dist/docx/exportRefs.js +3 -1
  31. package/dist/docx/fidelity.d.ts +43 -0
  32. package/dist/docx/fidelity.js +64 -0
  33. package/dist/docx/formatting/attrs.d.ts +27 -0
  34. package/dist/docx/formatting/attrs.js +31 -0
  35. package/dist/docx/formatting/context.d.ts +31 -0
  36. package/dist/docx/formatting/context.js +42 -0
  37. package/dist/docx/formatting/direct.d.ts +6 -5
  38. package/dist/docx/formatting/direct.js +52 -81
  39. package/dist/docx/formatting/resolve.d.ts +45 -0
  40. package/dist/docx/formatting/resolve.js +140 -0
  41. package/dist/docx/formatting/runProperties.d.ts +93 -0
  42. package/dist/docx/formatting/runProperties.js +316 -0
  43. package/dist/docx/formatting/styles.js +3 -3
  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 +13 -22
  48. package/dist/docx/identities.d.ts +67 -0
  49. package/dist/docx/identities.js +174 -0
  50. package/dist/docx/importDocx.d.ts +12 -1
  51. package/dist/docx/importDocx.js +72 -79
  52. package/dist/docx/importParagraph.d.ts +1 -1
  53. package/dist/docx/importParagraph.js +4 -3
  54. package/dist/docx/importTable.d.ts +1 -1
  55. package/dist/docx/importTable.js +17 -1
  56. package/dist/docx/invariants.d.ts +33 -0
  57. package/dist/docx/invariants.js +256 -0
  58. package/dist/docx/media.d.ts +6 -4
  59. package/dist/docx/media.js +6 -37
  60. package/dist/docx/newLists.d.ts +20 -0
  61. package/dist/docx/newLists.js +36 -0
  62. package/dist/docx/notes.js +6 -12
  63. package/dist/docx/numberingPlanner.d.ts +8 -0
  64. package/dist/docx/numberingPlanner.js +19 -0
  65. package/dist/docx/packageParts.d.ts +42 -0
  66. package/dist/docx/packageParts.js +135 -0
  67. package/dist/docx/pageGeometry.d.ts +2 -0
  68. package/dist/docx/pageGeometry.js +18 -9
  69. package/dist/docx/paraProps.d.ts +10 -22
  70. package/dist/docx/paraProps.js +75 -99
  71. package/dist/docx/partPlan.d.ts +36 -0
  72. package/dist/docx/partPlan.js +59 -0
  73. package/dist/docx/protectionPolicy.d.ts +127 -0
  74. package/dist/docx/protectionPolicy.js +169 -0
  75. package/dist/docx/relationships.d.ts +1 -1
  76. package/dist/docx/relationships.js +15 -15
  77. package/dist/docx/runProps.d.ts +9 -22
  78. package/dist/docx/runProps.js +15 -168
  79. package/dist/docx/scan.js +20 -52
  80. package/dist/docx/sdt.js +14 -37
  81. package/dist/docx/sdtProps.d.ts +8 -1
  82. package/dist/docx/sdtProps.js +10 -0
  83. package/dist/docx/serializeBlock.d.ts +2 -0
  84. package/dist/docx/serializeBlock.js +9 -7
  85. package/dist/docx/serializeParagraph.d.ts +2 -1
  86. package/dist/docx/serializeParagraph.js +25 -14
  87. package/dist/docx/serializeTable.js +63 -32
  88. package/dist/docx/session.d.ts +42 -14
  89. package/dist/docx/session.js +43 -17
  90. package/dist/docx/storyProjection.d.ts +36 -0
  91. package/dist/docx/storyProjection.js +23 -0
  92. package/dist/docx/tableFormatting/editing.js +130 -185
  93. package/dist/docx/tableFormatting/reading.d.ts +16 -6
  94. package/dist/docx/tableFormatting/reading.js +40 -20
  95. package/dist/docx/tableTemplate.js +37 -5
  96. package/dist/docx/theme.d.ts +0 -6
  97. package/dist/docx/theme.js +0 -8
  98. package/dist/download.d.ts +8 -5
  99. package/dist/download.js +2 -0
  100. package/dist/editor/clipboard/images.js +17 -3
  101. package/dist/editor/clipboard/inlineFormatting.d.ts +7 -0
  102. package/dist/editor/clipboard/inlineFormatting.js +20 -30
  103. package/dist/editor/commands/breakCommands.js +4 -3
  104. package/dist/editor/commands/canRunCommand.d.ts +2 -2
  105. package/dist/editor/commands/canRunCommand.js +1 -1
  106. package/dist/editor/commands/comments/editing.d.ts +6 -2
  107. package/dist/editor/commands/comments/editing.js +21 -36
  108. package/dist/editor/commands/exportQueries.d.ts +15 -0
  109. package/dist/editor/commands/exportQueries.js +14 -0
  110. package/dist/editor/commands/fidelityQueries.d.ts +12 -0
  111. package/dist/editor/commands/fidelityQueries.js +8 -0
  112. package/dist/editor/commands/formatting/editing.d.ts +2 -2
  113. package/dist/editor/commands/formatting/editing.js +26 -108
  114. package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
  115. package/dist/editor/commands/formatting/propertyCommands.js +103 -0
  116. package/dist/editor/commands/formatting/shared.d.ts +3 -3
  117. package/dist/editor/commands/formatting/shared.js +5 -2
  118. package/dist/editor/commands/historyCommands.js +2 -1
  119. package/dist/editor/commands/indentCommands.js +5 -4
  120. package/dist/editor/commands/index.d.ts +11 -0
  121. package/dist/editor/commands/index.js +5 -0
  122. package/dist/editor/commands/linkCommands.js +5 -6
  123. package/dist/editor/commands/listCommands.js +8 -10
  124. package/dist/editor/commands/lockCommands.d.ts +7 -1
  125. package/dist/editor/commands/lockCommands.js +35 -37
  126. package/dist/editor/commands/paragraphCommands.js +28 -31
  127. package/dist/editor/commands/spacingCommands.js +1 -1
  128. package/dist/editor/commands/tabCommands.js +4 -3
  129. package/dist/editor/createEditor.d.ts +17 -29
  130. package/dist/editor/createEditor.js +61 -67
  131. package/dist/editor/documentStyles.d.ts +11 -35
  132. package/dist/editor/documentStyles.js +9 -52
  133. package/dist/editor/editorDocument.d.ts +56 -0
  134. package/dist/editor/editorDocument.js +74 -0
  135. package/dist/editor/externalClipboard.js +166 -33
  136. package/dist/editor/insertImage.js +4 -3
  137. package/dist/editor/insertTable.js +4 -3
  138. package/dist/editor/paragraphEdits.d.ts +11 -18
  139. package/dist/editor/paragraphEdits.js +7 -16
  140. package/dist/editor/plugins/displayDerivation.d.ts +47 -0
  141. package/dist/editor/plugins/displayDerivation.js +78 -0
  142. package/dist/editor/plugins/documentProtection.d.ts +3 -3
  143. package/dist/editor/plugins/imagePaste.js +4 -3
  144. package/dist/editor/plugins/keymap.js +18 -3
  145. package/dist/editor/plugins/lockedContent.d.ts +4 -4
  146. package/dist/editor/plugins/lockedContent.js +1 -1
  147. package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
  148. package/dist/editor/plugins/numberingDecorations.js +7 -17
  149. package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
  150. package/dist/editor/plugins/paragraphDisplay.js +51 -0
  151. package/dist/editor/plugins/tabLayout.js +1 -1
  152. package/dist/editor/plugins/tableDisplay.d.ts +6 -0
  153. package/dist/editor/plugins/tableDisplay.js +16 -0
  154. package/dist/index.d.ts +2 -0
  155. package/dist/model/format.d.ts +30 -8
  156. package/dist/model/format.js +35 -22
  157. package/dist/model/tabStops.d.ts +9 -0
  158. package/dist/model/tabStops.js +18 -0
  159. package/dist/numbering/listTemplate.js +49 -10
  160. package/dist/numbering/parseNumbering.d.ts +14 -1
  161. package/dist/numbering/parseNumbering.js +35 -22
  162. package/dist/numbering/writeNumbering.d.ts +3 -4
  163. package/dist/numbering/writeNumbering.js +14 -25
  164. package/dist/ooxml/childOrder.d.ts +34 -0
  165. package/dist/ooxml/childOrder.js +496 -0
  166. package/dist/ooxml/element.d.ts +65 -0
  167. package/dist/ooxml/element.js +68 -0
  168. package/dist/ooxml/errors.d.ts +3 -2
  169. package/dist/ooxml/fragment.d.ts +53 -0
  170. package/dist/ooxml/fragment.js +76 -0
  171. package/dist/ooxml/image.d.ts +4 -0
  172. package/dist/ooxml/image.js +3 -5
  173. package/dist/ooxml/names.d.ts +27 -0
  174. package/dist/ooxml/names.js +29 -0
  175. package/dist/ooxml/partSplice.d.ts +67 -0
  176. package/dist/ooxml/partSplice.js +169 -0
  177. package/dist/ooxml/precedence.d.ts +31 -0
  178. package/dist/ooxml/precedence.js +51 -0
  179. package/dist/ooxml/props.d.ts +112 -0
  180. package/dist/ooxml/props.js +214 -0
  181. package/dist/ooxml/simpleTypes.d.ts +103 -0
  182. package/dist/ooxml/simpleTypes.js +182 -0
  183. package/dist/ooxml/tabStops.js +8 -27
  184. package/dist/ooxml/tagScan.d.ts +34 -0
  185. package/dist/ooxml/tagScan.js +108 -0
  186. package/dist/ooxml/units.d.ts +25 -13
  187. package/dist/ooxml/units.js +65 -31
  188. package/dist/ooxml/xml.d.ts +52 -0
  189. package/dist/ooxml/xml.js +64 -5
  190. package/dist/page/blockKinds.d.ts +103 -0
  191. package/dist/page/blockKinds.js +11 -0
  192. package/dist/page/kinds/index.d.ts +6 -0
  193. package/dist/page/kinds/index.js +10 -0
  194. package/dist/page/kinds/paragraphKind.d.ts +10 -0
  195. package/dist/page/kinds/paragraphKind.js +71 -0
  196. package/dist/page/kinds/tableKind.d.ts +10 -0
  197. package/dist/page/kinds/tableKind.js +178 -0
  198. package/dist/page/measureBlocks.d.ts +3 -1
  199. package/dist/page/measureBlocks.js +24 -25
  200. package/dist/page/pageDecorations.d.ts +27 -28
  201. package/dist/page/pageDecorations.js +70 -151
  202. package/dist/page/pageLayout.d.ts +10 -62
  203. package/dist/page/pageLayout.js +60 -53
  204. package/dist/page/usePageLayout.d.ts +2 -2
  205. package/dist/page/usePageLayout.js +3 -11
  206. package/dist/schema/attrRoles.d.ts +42 -0
  207. package/dist/schema/attrRoles.js +141 -0
  208. package/dist/schema/displayDerivation.d.ts +82 -0
  209. package/dist/schema/displayDerivation.js +130 -0
  210. package/dist/schema/docxSchema.d.ts +9 -0
  211. package/dist/schema/docxSchema.js +237 -114
  212. package/dist/schema/editGuard.d.ts +99 -0
  213. package/dist/schema/editGuard.js +43 -0
  214. package/dist/schema/guards.d.ts +91 -0
  215. package/dist/schema/guards.js +108 -0
  216. package/dist/schema/index.d.ts +2 -0
  217. package/dist/schema/index.js +2 -0
  218. package/dist/schema/locks.d.ts +17 -77
  219. package/dist/schema/locks.js +26 -70
  220. package/dist/schema/preservedGuards.d.ts +50 -0
  221. package/dist/schema/preservedGuards.js +80 -0
  222. package/dist/schema/protection.d.ts +17 -4
  223. package/dist/schema/protection.js +4 -2
  224. package/dist/schema/sourceEquality.d.ts +19 -0
  225. package/dist/schema/sourceEquality.js +39 -0
  226. package/dist/styles/inlineStyle.js +15 -6
  227. package/dist/table/cellFormatting.d.ts +8 -1
  228. package/dist/table/cellFormatting.js +10 -17
  229. package/dist/table/commands.d.ts +2 -2
  230. package/dist/table/commands.js +20 -18
  231. package/dist/table/format.d.ts +3 -0
  232. package/dist/table/format.js +3 -9
  233. package/dist/table/gridBorders.d.ts +14 -16
  234. package/dist/table/gridBorders.js +3 -41
  235. package/dist/table/index.d.ts +2 -2
  236. package/dist/table/merge.d.ts +4 -8
  237. package/dist/table/merge.js +5 -5
  238. package/package.json +10 -3
  239. package/dist/docx/comments/contentTypes.d.ts +0 -7
  240. package/dist/docx/comments/contentTypes.js +0 -38
  241. package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
  242. package/dist/docx/formatting/effectiveParagraph.js +0 -81
  243. package/dist/docx/propsXml.d.ts +0 -49
  244. package/dist/docx/propsXml.js +0 -302
  245. package/dist/docx/uniqueControls.d.ts +0 -14
  246. package/dist/docx/uniqueControls.js +0 -62
  247. package/dist/editor/plugins/bookmarkProtection.d.ts +0 -3
  248. package/dist/editor/plugins/bookmarkProtection.js +0 -28
  249. package/dist/editor/plugins/commentReservations.d.ts +0 -5
  250. package/dist/editor/plugins/commentReservations.js +0 -26
  251. package/dist/editor/plugins/noteProtection.d.ts +0 -3
  252. package/dist/editor/plugins/noteProtection.js +0 -25
  253. package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
  254. package/dist/editor/plugins/styledParagraphs.js +0 -65
  255. package/dist/page/tableMeasurements.d.ts +0 -10
  256. package/dist/page/tableMeasurements.js +0 -115
@@ -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,8 +4,7 @@ import {
4
4
  } from "prosemirror-state";
5
5
  import { toParagraphFormat } from "../../model/format.js";
6
6
  import { docxSchema } from "../../schema/index.js";
7
- import { replacementShut } from "../../schema/locks.js";
8
- import { editsShut } from "../../schema/protectionState.js";
7
+ import { editShut, selectionIntents } from "../../schema/guards.js";
9
8
  function isOrdinaryParagraph(state) {
10
9
  const { $from } = state.selection;
11
10
  if ($from.parent.type !== docxSchema.nodes.paragraph || toParagraphFormat($from.parent.attrs.format)?.numbering) {
@@ -18,7 +17,9 @@ function isOrdinaryParagraph(state) {
18
17
  }
19
18
  var insertTab = (state, dispatch) => {
20
19
  const { selection } = state;
21
- if (!(selection instanceof TextSelection) || !selection.$from.sameParent(selection.$to) || !isOrdinaryParagraph(state) || editsShut(state) || replacementShut(selection, state.doc)) {
20
+ if (!(selection instanceof TextSelection) || !selection.$from.sameParent(selection.$to) || !isOrdinaryParagraph(state) || selectionIntents(selection, "replace").some(
21
+ (intent) => editShut(state, intent)
22
+ )) {
22
23
  return false;
23
24
  }
24
25
  if (dispatch) {
@@ -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,24 +14,28 @@ 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
- import { bookmarkProtection } from "./plugins/bookmarkProtection.js";
29
25
  import { columnResize } from "./plugins/columnResize.js";
30
26
  import { commentDecorations } from "./plugins/commentDecorations.js";
31
- import { commentReservations } from "./plugins/commentReservations.js";
27
+ import {
28
+ displayDerivation,
29
+ withDerivedDisplay
30
+ } from "./plugins/displayDerivation.js";
32
31
  import { documentProtection } from "./plugins/documentProtection.js";
33
32
  import { imagePaste } from "./plugins/imagePaste.js";
34
33
  import { docxKeymap, historyKeys } from "./plugins/keymap.js";
35
34
  import { linkPanel } from "./plugins/linkPanel.js";
36
35
  import { listInputRules } from "./plugins/listInputRules.js";
37
36
  import { lockedContent } from "./plugins/lockedContent.js";
38
- import { noteProtection } from "./plugins/noteProtection.js";
39
37
  import { numberingMarkers } from "./plugins/numberingDecorations.js";
40
38
  import { rowResize } from "./plugins/rowResize.js";
41
- import { styledParagraphs } from "./plugins/styledParagraphs.js";
42
39
  import { tabCaret } from "./plugins/tabCaret.js";
43
40
  import { tabDecorations } from "./plugins/tabDecorations.js";
44
41
  import { tabLayout } from "./plugins/tabLayout.js";
@@ -47,41 +44,32 @@ import { tabPointer } from "./plugins/tabPointer.js";
47
44
  import { textContextMenu } from "./plugins/textContextMenu.js";
48
45
  import { ImageNodeView } from "./views/imageResize.js";
49
46
  import { runMarkView } from "./views/runMarkView.js";
50
- function createEditorState(doc, {
51
- numbering = EMPTY_NUMBERING,
52
- styles = NO_STYLES,
53
- defaults = NO_DOCUMENT_DEFAULTS,
54
- paragraphDefaults = {},
55
- canStartNewList = true,
56
- consumerPlugins = [],
57
- paragraphStyles = [],
58
- contextMenus = true,
59
- geometry = A4_PORTRAIT,
60
- defaultTabStopPt = DEFAULT_TAB_STOP_PT,
61
- reservedCommentIds = [],
62
- reservedCommentParaIds = [],
63
- protection = "none",
64
- author = null,
65
- editableComments = "own"
66
- } = {}) {
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;
67
56
  return EditorState.create({
68
- 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),
69
60
  plugins: [
70
61
  // Consumer plugins lead the array. ProseMirror walks the plugins in order and takes the
71
62
  // first answer for a keypress, a paste, a drop or any other DOM event, so this is the
72
63
  // only place from which a consumer handler can win over the built-in one.
73
64
  ...consumerPlugins,
74
- // Refuses every edit inside a locked content control, whoever asked for it. It is not
75
- // optional: a document that locked a part of itself stays locked in every consumer.
76
- // The same guard refuses what the protection below shuts.
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),
68
+ // Refuses every edit no guard in `schema/guards` lets through, whoever asked for it. It is
69
+ // not optional: a document that locked a part of itself stays locked in every consumer, and
70
+ // the preserved bookmark markers and note references stay where the file put them.
77
71
  lockedContent(),
78
72
  documentProtection({ protection, author, editableComments }),
79
- // Bookmark ranges are preserved rather than edited, so neither half may disappear.
80
- bookmarkProtection(),
81
- // Note bodies are display-only, so their imported main-story references stay paired.
82
- noteProtection(),
83
- // An orphan Comments-part entry still owns its id and must not be replaced by a new comment.
84
- commentReservations(reservedCommentIds, reservedCommentParaIds),
85
73
  history(),
86
74
  keymap(docxKeymap),
87
75
  historyKeys(),
@@ -108,52 +96,57 @@ function createEditorState(doc, {
108
96
  tabPointer(),
109
97
  tabLayout(),
110
98
  tabCaret(),
111
- // Keeps table-cell lines aligned with OOXML precedence after an edit
112
- gridBorders(),
113
- // Reads the document's styles into the paragraphs an edit built from nothing
114
- 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(),
115
102
  // Receiving a right-click means taking the browser's own menu away, so both of these stand
116
103
  // or fall together with the menus the editor draws. The text menu stands ahead of the table
117
104
  // menu, and hands a click with nothing selected inside a cell back to it
118
105
  ...contextMenus ? [textContextMenu(), tableContextMenu()] : [],
119
- numberingMarkers(numbering, canStartNewList),
106
+ numberingMarkers(),
120
107
  // Values only go in when page display is turned on
121
- pageDecorations(),
122
- documentStyleTable(
123
- styles,
124
- defaults,
125
- paragraphStyles,
126
- geometry,
127
- paragraphDefaults,
128
- numbering,
129
- defaultTabStopPt
130
- )
108
+ pageDecorations()
131
109
  ]
132
110
  });
133
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
+ }
134
126
  function createEditorView({
135
127
  mount,
136
128
  state,
137
- defaults,
138
- geometry = A4_PORTRAIT,
139
129
  fontFallbacks = DEFAULT_FONT_FALLBACKS,
140
130
  onStateChange
141
131
  }) {
142
- const sheetStyle = `${pageGeometryStyle(pagePixels(geometry))};${documentDefaultsStyle(defaults, fontFallbacks)};`;
143
132
  const view = new EditorView(mount, {
144
133
  state,
145
134
  // A protection that shuts the body shuts typing with it, and is read off the state so that a
146
135
  // mode switched on an open document takes effect without a new view. Selecting stays open
147
136
  // either way, which is what a reader marking a stretch for a comment needs
148
137
  editable: (current) => !editsShut(current),
149
- attributes: (current) => ({
150
- class: editorClassNames.sheet,
151
- // The paper first, so a document that names one is drawn on it from the first frame
152
- style: `${sheetStyle}tab-size:${documentDefaultTabStopPt(current)}pt`,
153
- // A sheet that takes no typing is no longer focusable of itself, so a reader or a commenter
154
- // is handed the focus another way: the keys reach it, and the selection stays its own
155
- ...editsShut(current) ? { tabindex: "0" } : {}
156
- }),
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
+ },
157
150
  // The schema can only draw a run with the default fallback fonts, so this editor draws its own
158
151
  markViews: { run: runMarkView(fontFallbacks) },
159
152
  // An image is drawn by a view of its own, which is what carries the resize handles
@@ -170,5 +163,6 @@ function createEditorView({
170
163
  }
171
164
  export {
172
165
  createEditorState,
173
- createEditorView
166
+ createEditorView,
167
+ editorStateForSession
174
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 {};
@@ -1,47 +1,24 @@
1
1
  // src/editor/documentStyles.ts
2
- import { Plugin, PluginKey } from "prosemirror-state";
3
- import { DEFAULT_TAB_STOP_PT } from "../docx/documentSettings.js";
4
2
  import {
5
- NO_DOCUMENT_DEFAULTS,
6
- NO_PARAGRAPH_FORMATTING,
7
- NO_STYLES
8
- } from "../docx/formatting.js";
9
- import {
10
- A4_PORTRAIT,
11
3
  bodyHeightTwips,
12
4
  bodyWidth,
13
5
  twipsToPx
14
6
  } from "../docx/pageGeometry.js";
15
- import { EMPTY_NUMBERING } from "../numbering/parseNumbering.js";
16
- var NO_PARAGRAPH_STYLES = [];
17
- var documentKey = new PluginKey("docxEditorDocument");
18
- function documentStyles(state) {
19
- return documentKey.getState(state)?.styles ?? NO_STYLES;
7
+ import { documentOf } from "./editorDocument.js";
8
+ function documentFormatting(state) {
9
+ return documentOf(state).formatting;
20
10
  }
21
11
  function documentDefaults(state) {
22
- return documentKey.getState(state)?.defaults ?? NO_DOCUMENT_DEFAULTS;
23
- }
24
- function documentParagraphFormatting(state) {
25
- const info = documentKey.getState(state);
26
- if (!info) return NO_PARAGRAPH_FORMATTING;
27
- return {
28
- styles: info.styles,
29
- defaultStyleId: info.paragraphStyles.find((style) => style.isDefault)?.id ?? null,
30
- defaults: info.paragraphDefaults,
31
- numbering: info.numbering
32
- };
12
+ return documentOf(state).defaults;
33
13
  }
34
14
  function documentParagraphStyles(state) {
35
- return documentKey.getState(state)?.paragraphStyles ?? NO_PARAGRAPH_STYLES;
36
- }
37
- function defaultParagraphStyleId(state) {
38
- return documentParagraphStyles(state).find((style) => style.isDefault)?.id ?? null;
15
+ return documentOf(state).paragraphStyles;
39
16
  }
40
17
  function documentGeometry(state) {
41
- return documentKey.getState(state)?.geometry ?? A4_PORTRAIT;
18
+ return documentOf(state).geometry;
42
19
  }
43
20
  function documentDefaultTabStopPt(state) {
44
- return documentKey.getState(state)?.defaultTabStopPt ?? DEFAULT_TAB_STOP_PT;
21
+ return documentOf(state).defaultTabStopPt;
45
22
  }
46
23
  function documentBodyWidthPx(state) {
47
24
  return bodyWidth(documentGeometry(state)).px;
@@ -49,32 +26,12 @@ function documentBodyWidthPx(state) {
49
26
  function documentBodyHeightPx(state) {
50
27
  return twipsToPx(bodyHeightTwips(documentGeometry(state)));
51
28
  }
52
- function documentStyleTable(styles, defaults = NO_DOCUMENT_DEFAULTS, paragraphStyles = NO_PARAGRAPH_STYLES, geometry = A4_PORTRAIT, paragraphDefaults = {}, numbering = EMPTY_NUMBERING, defaultTabStopPt = DEFAULT_TAB_STOP_PT) {
53
- return new Plugin({
54
- key: documentKey,
55
- state: {
56
- init: () => ({
57
- styles,
58
- defaults,
59
- paragraphDefaults,
60
- numbering,
61
- paragraphStyles,
62
- geometry,
63
- defaultTabStopPt
64
- }),
65
- apply: (_tr, current) => current
66
- }
67
- });
68
- }
69
29
  export {
70
- defaultParagraphStyleId,
71
30
  documentBodyHeightPx,
72
31
  documentBodyWidthPx,
73
32
  documentDefaultTabStopPt,
74
33
  documentDefaults,
34
+ documentFormatting,
75
35
  documentGeometry,
76
- documentParagraphFormatting,
77
- documentParagraphStyles,
78
- documentStyleTable,
79
- documentStyles
36
+ documentParagraphStyles
80
37
  };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * What the opened document laid down, held as one value: the formatting context every display
3
+ * value is resolved against, the paper the body is written on, and the identifiers its comment
4
+ * parts have already spent.
5
+ *
6
+ * Commands and the toolbar know nothing about the session, so the snapshot stands for it on their
7
+ * behalf, and `editorDocumentOf` is the one place a session is read into editor values: a screen
8
+ * and a test that open the same document hold the same values.
9
+ */
10
+ import { type EditorState, Plugin } from "prosemirror-state";
11
+ import { type FormattingContext, type ParagraphStyleOption } from "../docx/formatting";
12
+ import { type PageGeometry } from "../docx/pageGeometry";
13
+ import type { SessionStore } from "../docx/session";
14
+ import type { DocumentDefaults } from "../model/format";
15
+ /** The document-level values one editing state is built on */
16
+ export interface EditorDocument {
17
+ /** The document these values were read from. Null for a state built without one */
18
+ readonly session: SessionStore | null;
19
+ /** The style chain, the defaults and the list definitions a paragraph's and a run's display values are resolved against */
20
+ readonly formatting: FormattingContext;
21
+ readonly defaults: DocumentDefaults;
22
+ /** The styles the document defines for the style picker to offer */
23
+ readonly paragraphStyles: ParagraphStyleOption[];
24
+ /**
25
+ * Whether the document has a place (numbering.xml) to write the definition of a new list.
26
+ * A state built without opening a document assumes that place exists and behaves as every
27
+ * state did before the question was asked.
28
+ */
29
+ readonly canStartNewList: boolean;
30
+ /** The paper the document is written on, which decides the width a new table is fitted to */
31
+ readonly geometry: PageGeometry;
32
+ /** The distance between automatic tab stops when no custom stop applies */
33
+ readonly defaultTabStopPt: number;
34
+ /** Every id already present in the opened Comments part, including unreferenced entries */
35
+ readonly reservedCommentIds: ReadonlySet<string>;
36
+ /** Every paragraph id present in the opened comment parts, including orphan extension entries */
37
+ readonly reservedCommentParaIds: ReadonlySet<string>;
38
+ }
39
+ /** What a state built without an opened document answers: the same as nothing being written down */
40
+ export declare const NO_DOCUMENT: EditorDocument;
41
+ /** The one place an opened document is read into the values the editor holds */
42
+ export declare function editorDocumentOf(session: SessionStore): EditorDocument;
43
+ /** The document the state was built for. `NO_DOCUMENT` for a state built without one */
44
+ export declare function documentOf(state: EditorState): EditorDocument;
45
+ /**
46
+ * Holds the snapshot for the lifetime of the state.
47
+ *
48
+ * It is derived again only where a document-level edit could have been recorded, so an ordinary
49
+ * edit and a selection move both leave the same object behind, allowing the sheet's style to be
50
+ * cached against that identity.
51
+ */
52
+ export declare function editorDocument(document: EditorDocument): Plugin<EditorDocument>;
53
+ /** The comment ids the opened document already spent, which a new comment may not take */
54
+ export declare function reservedCommentIds(state: EditorState): ReadonlySet<string>;
55
+ /** The paragraph ids the opened comment parts already spent */
56
+ export declare function reservedCommentParaIds(state: EditorState): ReadonlySet<string>;