@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
@@ -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>;
@@ -0,0 +1,74 @@
1
+ // src/editor/editorDocument.ts
2
+ import { Plugin, PluginKey } from "prosemirror-state";
3
+ import { DEFAULT_TAB_STOP_PT } from "../docx/documentSettings.js";
4
+ import {
5
+ NO_DOCUMENT_DEFAULTS,
6
+ NO_FORMATTING
7
+ } from "../docx/formatting.js";
8
+ import { A4_PORTRAIT } from "../docx/pageGeometry.js";
9
+ var NO_IDS = /* @__PURE__ */ new Set();
10
+ var NO_PARAGRAPH_STYLES = [];
11
+ var NO_DOCUMENT = {
12
+ session: null,
13
+ formatting: NO_FORMATTING,
14
+ defaults: NO_DOCUMENT_DEFAULTS,
15
+ paragraphStyles: NO_PARAGRAPH_STYLES,
16
+ canStartNewList: true,
17
+ geometry: A4_PORTRAIT,
18
+ defaultTabStopPt: DEFAULT_TAB_STOP_PT,
19
+ reservedCommentIds: NO_IDS,
20
+ reservedCommentParaIds: NO_IDS
21
+ };
22
+ function reservedParaIds(session) {
23
+ const paraIds = /* @__PURE__ */ new Set();
24
+ for (const comment of session.comments.ordered) {
25
+ if (comment.paraId !== null) paraIds.add(comment.paraId);
26
+ }
27
+ for (const extension of session.comments.extendedOrdered) {
28
+ paraIds.add(extension.paraId);
29
+ }
30
+ return paraIds;
31
+ }
32
+ function editorDocumentOf(session) {
33
+ return {
34
+ session,
35
+ formatting: session.formatting,
36
+ defaults: session.defaults,
37
+ paragraphStyles: session.paragraphStyles,
38
+ canStartNewList: session.numberingPartPath !== null,
39
+ geometry: session.geometry,
40
+ defaultTabStopPt: session.defaultTabStopPt,
41
+ reservedCommentIds: new Set(session.comments.byId.keys()),
42
+ reservedCommentParaIds: reservedParaIds(session)
43
+ };
44
+ }
45
+ var editorDocumentKey = new PluginKey("docxEditorDocument");
46
+ function documentOf(state) {
47
+ return editorDocumentKey.getState(state) ?? NO_DOCUMENT;
48
+ }
49
+ function derive(session, _doc) {
50
+ return editorDocumentOf(session);
51
+ }
52
+ function editorDocument(document) {
53
+ return new Plugin({
54
+ key: editorDocumentKey,
55
+ state: {
56
+ init: () => document,
57
+ apply: (tr, current, old) => current.session === null || tr.doc.attrs === old.doc.attrs ? current : derive(current.session, tr.doc)
58
+ }
59
+ });
60
+ }
61
+ function reservedCommentIds(state) {
62
+ return documentOf(state).reservedCommentIds;
63
+ }
64
+ function reservedCommentParaIds(state) {
65
+ return documentOf(state).reservedCommentParaIds;
66
+ }
67
+ export {
68
+ NO_DOCUMENT,
69
+ documentOf,
70
+ editorDocument,
71
+ editorDocumentOf,
72
+ reservedCommentIds,
73
+ reservedCommentParaIds
74
+ };
@@ -5,11 +5,12 @@ import {
5
5
  Slice
6
6
  } from "prosemirror-model";
7
7
  import { Plugin } from "prosemirror-state";
8
- import { effectiveParagraphFormat, styleIdOf } from "../docx/formatting.js";
9
- import { withParagraphStyle } from "../docx/paraProps.js";
8
+ import { paragraphAttrsFor, styleIdOf } from "../docx/formatting.js";
9
+ import {
10
+ withListNumbering,
11
+ withParagraphStyle
12
+ } from "../docx/paraProps.js";
10
13
  import { MAX_ILVL, nextNumId } from "../numbering/listTemplate.js";
11
- import { elementXml } from "../ooxml/element.js";
12
- import { wName } from "../ooxml/names.js";
13
14
  import { docxSchema, isPageBreak } from "../schema/index.js";
14
15
  import { editorClassNames } from "../styles/classNames.js";
15
16
  import { PASTED_IMAGE_ATTRIBUTE } from "./clipboard/images.js";
@@ -21,12 +22,7 @@ import {
21
22
  withInlineStyle
22
23
  } from "./clipboard/inlineFormatting.js";
23
24
  import { listRefOf } from "./commands/listCommands.js";
24
- import {
25
- defaultParagraphStyleId,
26
- documentParagraphFormatting,
27
- documentParagraphStyles,
28
- documentStyles
29
- } from "./documentStyles.js";
25
+ import { documentFormatting, documentParagraphStyles } from "./documentStyles.js";
30
26
  import { insertPlainText } from "./plainText.js";
31
27
  import { moveCaretToDrop } from "./plugins/dropCaret.js";
32
28
  import {
@@ -242,12 +238,7 @@ function blockContext(state, parent, element, preserveParagraphStyle) {
242
238
  };
243
239
  }
244
240
  const styleId = destinationStyleId(state, sourceStyleId, level);
245
- const paragraph = styleId === null ? null : withParagraphStyle(
246
- null,
247
- styleId,
248
- documentStyles(state),
249
- defaultParagraphStyleId(state)
250
- );
241
+ const paragraph = styleId === null ? null : withParagraphStyle(null, styleId);
251
242
  const usesDestinationStyle = editorParagraph && (sourceStyleId === null || paragraph !== null);
252
243
  let inline = parent;
253
244
  if (paragraph === null && level !== null) {
@@ -258,38 +249,18 @@ function blockContext(state, parent, element, preserveParagraphStyle) {
258
249
  paragraph
259
250
  };
260
251
  }
261
- function listParagraphAttrs(state, list) {
252
+ function listParagraphProps(list) {
262
253
  if (!list || list.numId === null) return null;
263
- const ilvl = Math.min(MAX_ILVL, list.level);
264
- const pPr = elementXml(
265
- wName("pPr"),
266
- [],
267
- [
268
- elementXml(
269
- wName("numPr"),
270
- [],
271
- [
272
- elementXml(wName("ilvl"), [[wName("val"), `${ilvl}`]]),
273
- elementXml(wName("numId"), [[wName("val"), `${list.numId}`]])
274
- ]
275
- )
276
- ]
277
- );
278
- return {
279
- pPr,
280
- format: effectiveParagraphFormat(pPr, documentParagraphFormatting(state))
281
- };
254
+ return withListNumbering(null, {
255
+ numbering: { numId: list.numId, ilvl: Math.min(MAX_ILVL, list.level) },
256
+ indent: { kind: "keep" }
257
+ });
282
258
  }
283
259
  function paragraphAttrs(state, list, paragraph) {
284
- const listed = listParagraphAttrs(state, list);
285
- if (listed) return listed;
286
- return paragraph ? {
287
- pPr: paragraph.pPr,
288
- format: effectiveParagraphFormat(
289
- paragraph.pPr,
290
- documentParagraphFormatting(state)
291
- ),
292
- styleRun: paragraph.styleRun
260
+ const props = listParagraphProps(list) ?? paragraph;
261
+ return props ? {
262
+ pPr: props.pPr,
263
+ ...paragraphAttrsFor(props.pPr, documentFormatting(state))
293
264
  } : null;
294
265
  }
295
266
  function usedNumIds(state) {
@@ -4,7 +4,7 @@ import {
4
4
  TextSelection
5
5
  } from "prosemirror-state";
6
6
  import { createTableNode, isTableSide } from "../docx/tableTemplate.js";
7
- import { editsShut } from "../schema/protectionState.js";
7
+ import { editShut } from "../schema/guards.js";
8
8
  import { documentGeometry } from "./documentStyles.js";
9
9
  function isInTable($pos) {
10
10
  for (let depth = $pos.depth; depth > 0; depth -= 1) {
@@ -14,8 +14,9 @@ function isInTable($pos) {
14
14
  }
15
15
  function insertPosition(state) {
16
16
  const $from = state.selection.$from;
17
- if (editsShut(state) || $from.depth === 0 || isInTable($from)) return null;
18
- return $from.after(1);
17
+ if ($from.depth === 0 || isInTable($from)) return null;
18
+ const at = $from.after(1);
19
+ return editShut(state, { kind: "insert", at }) ? null : at;
19
20
  }
20
21
  function canInsertTable(state) {
21
22
  return insertPosition(state) !== null;
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import type { Node as PMNode } from "prosemirror-model";
10
10
  import type { EditorState, Transaction } from "prosemirror-state";
11
- import { type StyleTable } from "../docx/formatting";
12
11
  import type { ParagraphProps } from "../docx/paraProps";
13
12
  export interface ParagraphSpot {
14
13
  pos: number;
@@ -17,28 +16,22 @@ export interface ParagraphSpot {
17
16
  /** The paragraphs the selection spans. Selections covering several table cells are handled too */
18
17
  export declare function selectedParagraphs(state: EditorState): ParagraphSpot[];
19
18
  /**
20
- * The selected paragraphs a lock leaves editable, which is what every paragraph edit works on.
19
+ * The selected paragraphs the guards leave editable, which is what every paragraph edit works on.
21
20
  *
22
- * A locked stretch is left out rather than the whole edit refused, the policy character formatting
23
- * already follows (`commands/formattingCommands`): the guard turns down a whole transaction, so
24
- * asking for it would leave the rest of the selection unedited too. A selection the lock leaves
25
- * nothing of edits nothing, and the command reports that of its own accord, which is the disabled
26
- * state of the control that runs it.
21
+ * A shut paragraph is left out rather than the whole edit refused, the policy character formatting
22
+ * already follows (`schema/guards`): the guard turns down a whole transaction, so asking for it
23
+ * would leave the rest of the selection unedited too. A selection the guards leave nothing of edits
24
+ * nothing, and the command reports that of its own accord, which is the disabled state of the
25
+ * control that runs it.
27
26
  *
28
- * Only the paragraphs of a locked cell are shut. A paragraph merely holding a locked control keeps
29
- * its own alignment, indent and style, which is what `insideLockedCell` says and
30
- * `rangeTouchesLocked` would not (`schema/locks`).
31
- *
32
- * A protection that shuts the body leaves no paragraph editable (`schema/protection`).
27
+ * A paragraph is rewritten around its content, which is the block intent: only the paragraphs of a
28
+ * locked cell are shut, and a paragraph merely holding a locked control keeps its own alignment,
29
+ * indent and style. A protection that shuts the body shuts every one of them.
33
30
  */
34
31
  export declare function editableParagraphs(state: EditorState): ParagraphSpot[];
35
32
  /** The original formatting XML this paragraph holds. Null when there is none */
36
33
  export declare function paragraphPPr(node: PMNode): string | null;
37
- /**
38
- * How to edit a single paragraph. Null skips that paragraph.
39
- * The style table and the document's default paragraph style come along, because the display values
40
- * of the edited fragment are read back with the style the paragraph wears laid underneath.
41
- */
42
- export type ParagraphSurgery = (node: PMNode, styles: StyleTable, defaultStyleId: string | null) => ParagraphProps | null;
34
+ /** How to edit a single paragraph. Null skips that paragraph */
35
+ export type ParagraphSurgery = (node: PMNode) => ParagraphProps | null;
43
36
  /** Edits the selected paragraphs in a single transaction. Does nothing when there is nothing to edit */
44
37
  export declare function editParagraphs(state: EditorState, dispatch: ((tr: Transaction) => void) | undefined, surgery: ParagraphSurgery): boolean;
@@ -1,13 +1,8 @@
1
1
  // src/editor/paragraphEdits.ts
2
- import { effectiveParagraphFormat } from "../docx/formatting.js";
2
+ import { paragraphAttrsFor } from "../docx/formatting.js";
3
3
  import { docxSchema } from "../schema/index.js";
4
- import { insideLockedCell } from "../schema/locks.js";
5
- import { editsShut } from "../schema/protectionState.js";
6
- import {
7
- defaultParagraphStyleId,
8
- documentParagraphFormatting,
9
- documentStyles
10
- } from "./documentStyles.js";
4
+ import { editShut } from "../schema/guards.js";
5
+ import { documentFormatting } from "./documentStyles.js";
11
6
  function selectedParagraphs(state) {
12
7
  const spots = /* @__PURE__ */ new Map();
13
8
  for (const range of state.selection.ranges) {
@@ -20,9 +15,8 @@ function selectedParagraphs(state) {
20
15
  return Array.from(spots, ([pos, node]) => ({ pos, node }));
21
16
  }
22
17
  function editableParagraphs(state) {
23
- if (editsShut(state)) return [];
24
18
  return selectedParagraphs(state).filter(
25
- (spot) => !insideLockedCell(state.doc, spot.pos)
19
+ (spot) => !editShut(state, { kind: "block", at: spot.pos })
26
20
  );
27
21
  }
28
22
  function paragraphPPr(node) {
@@ -31,22 +25,19 @@ function paragraphPPr(node) {
31
25
  }
32
26
  function writeChanges(state, changed) {
33
27
  const tr = state.tr;
34
- const formatting = documentParagraphFormatting(state);
28
+ const formatting = documentFormatting(state);
35
29
  for (const { spot, props } of changed) {
36
30
  tr.setNodeMarkup(tr.mapping.map(spot.pos), void 0, {
37
31
  ...spot.node.attrs,
38
32
  pPr: props.pPr,
39
- format: effectiveParagraphFormat(props.pPr, formatting),
40
- styleRun: props.styleRun
33
+ ...paragraphAttrsFor(props.pPr, formatting)
41
34
  });
42
35
  }
43
36
  return tr;
44
37
  }
45
38
  function editParagraphs(state, dispatch, surgery) {
46
- const styles = documentStyles(state);
47
- const defaultStyleId = defaultParagraphStyleId(state);
48
39
  const changed = editableParagraphs(state).flatMap((spot) => {
49
- const props = surgery(spot.node, styles, defaultStyleId);
40
+ const props = surgery(spot.node);
50
41
  return props ? [{ spot, props }] : [];
51
42
  });
52
43
  if (changed.length === 0) return false;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Keeps every display value of the document current: the ones an edit moved, after that edit, and
3
+ * every one at once when the document snapshot the values are resolved against is replaced.
4
+ *
5
+ * The derivers are registered here and run through the one walk `schema/displayDerivation`
6
+ * defines. What a node maps back to is settled here as well, from the mapping of the transactions
7
+ * that changed the document: a node whose content survived those transactions is the node that
8
+ * stood where its opening maps back to, and one whose content did not is new. A node rewritten
9
+ * where it stands (`setNodeMarkup`) therefore still maps back to itself, which is what lets a
10
+ * table resized or a paragraph re-aligned be told from a table or a paragraph put in.
11
+ *
12
+ * The transaction this appends carries the display-only pass (`schema/guards`), since it changes
13
+ * nothing a lock or a protection answers for, and goes to the history as part of the edit it
14
+ * follows, so that one undo takes the edit and its values back together. The re-derivation after
15
+ * a snapshot change follows no edit and goes to the history not at all: the values follow the
16
+ * snapshot, and undoing whatever replaced the snapshot derives them again.
17
+ */
18
+ import type { Node as PMNode } from "prosemirror-model";
19
+ import { Plugin } from "prosemirror-state";
20
+ import { type DisplayDeriver } from "../../schema/displayDerivation";
21
+ import { type EditorDocument } from "../editorDocument";
22
+ /** What a deriver of this editor resolves against */
23
+ export interface DerivationContext {
24
+ readonly document: EditorDocument;
25
+ /**
26
+ * Where the composition the browser holds open stands, which a deriver leaves alone: rewriting
27
+ * the node it stands in redraws it, and a redraw under an open composition is what the browser
28
+ * answers by taking the composition down. Null while nothing is being composed, and while every
29
+ * value is being worked out again from nothing, when nothing may be left standing.
30
+ */
31
+ readonly composingAt: number | null;
32
+ }
33
+ export type DocumentDeriver = DisplayDeriver<DerivationContext>;
34
+ export declare const DISPLAY_DERIVERS: readonly DocumentDeriver[];
35
+ /**
36
+ * The document with every display value worked out against this snapshot, which is what a state
37
+ * is built over: the values a document arrived with were worked out against whatever opened it.
38
+ */
39
+ export declare function withDerivedDisplay(doc: PMNode, document: EditorDocument, derivers?: readonly DocumentDeriver[]): PMNode;
40
+ /**
41
+ * Derives the display values again after every change: for the nodes an edit moved, and for every
42
+ * node when the snapshot was replaced.
43
+ *
44
+ * An appended transaction is handed nothing but states, so the view an open composition is read
45
+ * from is the one the plugin is given when it mounts.
46
+ */
47
+ export declare function displayDerivation(derivers?: readonly DocumentDeriver[]): Plugin;
@@ -0,0 +1,78 @@
1
+ // src/editor/plugins/displayDerivation.ts
2
+ import { Plugin } from "prosemirror-state";
3
+ import { Mapping, Transform } from "prosemirror-transform";
4
+ import {
5
+ deriveDisplay,
6
+ displayOnly
7
+ } from "../../schema/displayDerivation.js";
8
+ import { documentOf } from "../editorDocument.js";
9
+ import { paragraphDisplay } from "./paragraphDisplay.js";
10
+ import { tableDisplay } from "./tableDisplay.js";
11
+ var DISPLAY_DERIVERS = [
12
+ tableDisplay,
13
+ paragraphDisplay
14
+ ];
15
+ var nothingBefore = () => null;
16
+ function withDerivedDisplay(doc, document, derivers = DISPLAY_DERIVERS) {
17
+ const transform = new Transform(doc);
18
+ deriveDisplay(
19
+ transform,
20
+ { document, composingAt: null },
21
+ derivers,
22
+ nothingBefore
23
+ );
24
+ return transform.doc;
25
+ }
26
+ function previousIn(before, transactions) {
27
+ const mapping = new Mapping();
28
+ for (const transaction of transactions) {
29
+ mapping.appendMapping(transaction.mapping);
30
+ }
31
+ const back = mapping.invert();
32
+ return (node, pos) => {
33
+ const inside = node.isLeaf ? pos : pos + 1;
34
+ if (back.mapResult(inside, 1).deleted) return null;
35
+ const was = before.nodeAt(back.map(pos, 1));
36
+ return was !== null && was.type === node.type ? was : null;
37
+ };
38
+ }
39
+ function composingAt(view, state) {
40
+ return view?.composing === true ? state.selection.from : null;
41
+ }
42
+ function displayDerivation(derivers = DISPLAY_DERIVERS) {
43
+ let live = null;
44
+ return new Plugin({
45
+ view(view) {
46
+ live = view;
47
+ return {
48
+ destroy() {
49
+ live = null;
50
+ }
51
+ };
52
+ },
53
+ appendTransaction(transactions, oldState, newState) {
54
+ const document = documentOf(newState);
55
+ const replaced = document !== documentOf(oldState);
56
+ if (!replaced && !transactions.some((transaction) => transaction.docChanged)) {
57
+ return null;
58
+ }
59
+ const tr = newState.tr.setMeta(displayOnly, true);
60
+ if (replaced) tr.setMeta("addToHistory", false);
61
+ deriveDisplay(
62
+ tr,
63
+ {
64
+ document,
65
+ composingAt: replaced ? null : composingAt(live, newState)
66
+ },
67
+ derivers,
68
+ replaced ? nothingBefore : previousIn(oldState.doc, transactions)
69
+ );
70
+ return tr.docChanged ? tr : null;
71
+ }
72
+ });
73
+ }
74
+ export {
75
+ DISPLAY_DERIVERS,
76
+ displayDerivation,
77
+ withDerivedDisplay
78
+ };
@@ -2,8 +2,7 @@
2
2
  import { isHistoryTransaction } from "prosemirror-history";
3
3
  import { Plugin, PluginKey } from "prosemirror-state";
4
4
  import { Decoration, DecorationSet } from "prosemirror-view";
5
- import { replacementShut } from "../../schema/locks.js";
6
- import { editsShut } from "../../schema/protectionState.js";
5
+ import { editShut, selectionIntents } from "../../schema/guards.js";
7
6
  import {
8
7
  hasResolvableClipboardImages,
9
8
  resolveClipboardImages
@@ -223,7 +222,9 @@ function imagePaste() {
223
222
  props: {
224
223
  decorations: (state) => imagePasteKey.getState(state)?.decorations,
225
224
  handlePaste(view, event) {
226
- if (editsShut(view.state) || replacementShut(view.state.selection, view.state.doc)) {
225
+ if (selectionIntents(view.state.selection, "replace").some(
226
+ (intent) => editShut(view.state, intent)
227
+ )) {
227
228
  return false;
228
229
  }
229
230
  if (view.state.selection.ranges.length > 1) return false;