@beyondwork/docx-react-component 1.0.42 → 1.0.45

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 (82) hide show
  1. package/README.md +17 -0
  2. package/package.json +5 -4
  3. package/src/api/editor-state-types.ts +110 -0
  4. package/src/api/public-types.ts +333 -4
  5. package/src/core/commands/formatting-commands.ts +7 -1
  6. package/src/core/commands/index.ts +60 -10
  7. package/src/core/commands/text-commands.ts +59 -0
  8. package/src/core/search/search-text.ts +15 -2
  9. package/src/core/selection/review-anchors.ts +131 -21
  10. package/src/index.ts +29 -1
  11. package/src/io/chart-preview-resolver.ts +281 -0
  12. package/src/io/docx-session.ts +692 -2
  13. package/src/io/export/build-app-properties-xml.ts +1 -1
  14. package/src/io/export/serialize-comments.ts +38 -9
  15. package/src/io/export/twip.ts +1 -1
  16. package/src/io/load-scheduler.ts +230 -0
  17. package/src/io/normalize/normalize-text.ts +116 -0
  18. package/src/io/ooxml/parse-comments.ts +0 -33
  19. package/src/io/ooxml/parse-complex-content.ts +14 -0
  20. package/src/io/ooxml/parse-main-document.ts +4 -0
  21. package/src/io/ooxml/workflow-payload-validator.ts +97 -1
  22. package/src/io/ooxml/workflow-payload.ts +172 -1
  23. package/src/preservation/opaque-region.ts +5 -0
  24. package/src/review/store/comment-remapping.ts +2 -2
  25. package/src/runtime/collab-session.ts +1 -1
  26. package/src/runtime/document-runtime.ts +661 -42
  27. package/src/runtime/edit-dispatch/dispatch-text-command.ts +98 -0
  28. package/src/runtime/edit-dispatch/index.ts +2 -0
  29. package/src/runtime/edit-dispatch/list-aware-dispatch.ts +125 -0
  30. package/src/runtime/editor-state-channel.ts +544 -0
  31. package/src/runtime/editor-state-integration.ts +217 -0
  32. package/src/runtime/editor-surface/capabilities.ts +411 -0
  33. package/src/runtime/layout/index.ts +2 -0
  34. package/src/runtime/layout/inert-layout-facet.ts +4 -0
  35. package/src/runtime/layout/layout-engine-instance.ts +63 -2
  36. package/src/runtime/layout/layout-engine-version.ts +41 -0
  37. package/src/runtime/layout/paginated-layout-engine.ts +211 -14
  38. package/src/runtime/layout/public-facet.ts +430 -1
  39. package/src/runtime/perf-counters.ts +28 -0
  40. package/src/runtime/prerender/cache-envelope.ts +29 -0
  41. package/src/runtime/prerender/cache-key.ts +66 -0
  42. package/src/runtime/prerender/font-fingerprint.ts +17 -0
  43. package/src/runtime/prerender/graph-canonicalize.ts +121 -0
  44. package/src/runtime/prerender/indexeddb-cache.ts +184 -0
  45. package/src/runtime/prerender/prerender-document.ts +145 -0
  46. package/src/runtime/render/block-fragment-projection.ts +2 -0
  47. package/src/runtime/render/render-frame-types.ts +17 -0
  48. package/src/runtime/render/render-kernel.ts +172 -29
  49. package/src/runtime/selection/post-edit-validator.ts +77 -0
  50. package/src/runtime/surface-projection.ts +45 -7
  51. package/src/runtime/workflow-markup.ts +71 -16
  52. package/src/ui/WordReviewEditor.tsx +142 -237
  53. package/src/ui/editor-command-bag.ts +14 -0
  54. package/src/ui/editor-runtime-boundary.ts +115 -12
  55. package/src/ui/editor-shell-view.tsx +10 -0
  56. package/src/ui/editor-surface-controller.tsx +5 -0
  57. package/src/ui/headless/selection-helpers.ts +10 -0
  58. package/src/ui/runtime-shortcut-dispatch.ts +28 -68
  59. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +62 -2
  60. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +281 -0
  61. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +48 -0
  62. package/src/ui-tailwind/editor-surface/paste-plain-text.ts +72 -0
  63. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +118 -8
  64. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +76 -165
  65. package/src/ui-tailwind/editor-surface/pm-schema.ts +170 -4
  66. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +58 -7
  67. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -0
  68. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +265 -0
  69. package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +8 -255
  70. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +47 -0
  71. package/src/ui-tailwind/index.ts +5 -1
  72. package/src/ui-tailwind/page-stack/tw-endnote-area.tsx +57 -0
  73. package/src/ui-tailwind/page-stack/tw-footnote-area.tsx +71 -0
  74. package/src/ui-tailwind/page-stack/tw-page-footer-band.tsx +73 -0
  75. package/src/ui-tailwind/page-stack/tw-page-header-band.tsx +74 -0
  76. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +477 -0
  77. package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +374 -0
  78. package/src/ui-tailwind/page-stack/use-visible-block-range.ts +157 -0
  79. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +155 -0
  80. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +77 -16
  81. package/src/ui-tailwind/theme/editor-theme.css +47 -14
  82. package/src/ui-tailwind/tw-review-workspace.tsx +303 -123
@@ -0,0 +1,98 @@
1
+ import type { DocumentRuntime } from "../document-runtime.ts";
2
+ import {
3
+ applyListAwareTextCommand,
4
+ type DispatchTextCommand,
5
+ type ListAwareDispatchDeps,
6
+ type ListAwareMutationResult,
7
+ type StoryMutationContext,
8
+ } from "./list-aware-dispatch.ts";
9
+
10
+ export type { DispatchTextCommand };
11
+
12
+ // TODO(Part 2): collapse DispatchContext into the runtime layer.
13
+ // The four UI-private helpers (getStoryMutationContext, dispatchStoryMutationResult,
14
+ // resolveActiveParagraphContext, toRuntimeSelectionSnapshot) currently live in
15
+ // WordReviewEditor.tsx for historical reasons but are pure runtime adapters with
16
+ // no React/UI dependencies. The four-shell refactor (R.1-R.4) will move them
17
+ // into src/runtime/edit-dispatch/, at which point this DI bundle dissolves.
18
+ export interface DispatchContext extends ListAwareDispatchDeps {
19
+ getStoryMutationContext(
20
+ runtime: DocumentRuntime,
21
+ command?: string,
22
+ ): StoryMutationContext | null;
23
+ dispatchStoryMutationResult(
24
+ runtime: DocumentRuntime,
25
+ context: StoryMutationContext,
26
+ result: ListAwareMutationResult,
27
+ timestamp: string,
28
+ ): void;
29
+ }
30
+
31
+ export function dispatchTextCommand(
32
+ runtime: DocumentRuntime,
33
+ command: DispatchTextCommand,
34
+ deps: DispatchContext,
35
+ ): void {
36
+ const context = deps.getStoryMutationContext(runtime, getMountedTextCommandName(command));
37
+ if (!context) {
38
+ return;
39
+ }
40
+
41
+ const effectiveSelectionMode = runtime.getInteractionGuardSnapshot().effectiveMode;
42
+ const listAwareResult = applyListAwareTextCommand(context, command, deps);
43
+ if (effectiveSelectionMode === "suggest" && listAwareResult) {
44
+ runtime.emitBlockedCommand(getMountedTextCommandName(command), [{
45
+ code: "suggesting_unsupported",
46
+ message: "List structure changes are not supported in suggesting mode.",
47
+ }]);
48
+ return;
49
+ }
50
+
51
+ if (listAwareResult) {
52
+ deps.dispatchStoryMutationResult(runtime, context, listAwareResult, context.timestamp);
53
+ return;
54
+ }
55
+
56
+ switch (command.type) {
57
+ case "insert-text":
58
+ runtime.applyActiveStoryTextCommand({ type: "text.insert", text: command.text });
59
+ return;
60
+ case "delete-backward":
61
+ runtime.applyActiveStoryTextCommand({ type: "text.delete-backward" });
62
+ return;
63
+ case "delete-forward":
64
+ runtime.applyActiveStoryTextCommand({ type: "text.delete-forward" });
65
+ return;
66
+ case "insert-tab":
67
+ runtime.applyActiveStoryTextCommand({ type: "text.insert-tab" });
68
+ return;
69
+ case "outdent-tab":
70
+ runtime.applyActiveStoryTextCommand({ type: "text.outdent-tab" });
71
+ return;
72
+ case "insert-hard-break":
73
+ runtime.applyActiveStoryTextCommand({ type: "text.insert-hard-break" });
74
+ return;
75
+ case "split-paragraph":
76
+ runtime.applyActiveStoryTextCommand({ type: "paragraph.split" });
77
+ return;
78
+ }
79
+ }
80
+
81
+ function getMountedTextCommandName(command: DispatchTextCommand): string {
82
+ switch (command.type) {
83
+ case "insert-text":
84
+ return "text.insert";
85
+ case "delete-backward":
86
+ return "text.delete-backward";
87
+ case "delete-forward":
88
+ return "text.delete-forward";
89
+ case "insert-tab":
90
+ return "text.insert-tab";
91
+ case "outdent-tab":
92
+ return "text.outdent-tab";
93
+ case "insert-hard-break":
94
+ return "text.insert-hard-break";
95
+ case "split-paragraph":
96
+ return "paragraph.split";
97
+ }
98
+ }
@@ -0,0 +1,2 @@
1
+ export { dispatchTextCommand } from "./dispatch-text-command.ts";
2
+ export type { DispatchTextCommand, DispatchContext } from "./dispatch-text-command.ts";
@@ -0,0 +1,125 @@
1
+ import type {
2
+ EditorSessionState,
3
+ EditorStoryTarget,
4
+ RuntimeRenderSnapshot,
5
+ SelectionSnapshot as PublicSelectionSnapshot,
6
+ SurfaceBlockSnapshot,
7
+ } from "../../api/public-types";
8
+ import { type SelectionSnapshot as InternalSelectionSnapshot } from "../../core/state/editor-state.ts";
9
+ import {
10
+ backspaceAtListStart,
11
+ indentListItems,
12
+ outdentListItems,
13
+ splitListParagraph,
14
+ } from "../../core/commands/list-commands.ts";
15
+
16
+ export type DispatchTextCommand =
17
+ | { type: "insert-text"; text: string }
18
+ | { type: "delete-backward" }
19
+ | { type: "delete-forward" }
20
+ | { type: "insert-tab" }
21
+ | { type: "outdent-tab" }
22
+ | { type: "insert-hard-break" }
23
+ | { type: "split-paragraph" };
24
+
25
+ export interface ListAwareParagraphContext {
26
+ paragraphIndex: number;
27
+ paragraph: Extract<SurfaceBlockSnapshot, { kind: "paragraph" }>;
28
+ atParagraphStart: boolean;
29
+ isEmpty: boolean;
30
+ }
31
+
32
+ export interface StoryMutationContext {
33
+ timestamp: string;
34
+ activeStory: EditorStoryTarget;
35
+ persistedDocument: EditorSessionState["canonicalDocument"];
36
+ localDocument: EditorSessionState["canonicalDocument"];
37
+ localSnapshot: RuntimeRenderSnapshot;
38
+ }
39
+
40
+ export interface ListAwareMutationResult {
41
+ changed: boolean;
42
+ document: EditorSessionState["canonicalDocument"];
43
+ selection: InternalSelectionSnapshot;
44
+ }
45
+
46
+ export interface ListAwareDispatchDeps {
47
+ resolveActiveParagraphContext(
48
+ snapshot: Pick<RuntimeRenderSnapshot, "surface" | "selection">,
49
+ ): ListAwareParagraphContext | null;
50
+ toRuntimeSelectionSnapshot(selection: PublicSelectionSnapshot): InternalSelectionSnapshot;
51
+ }
52
+
53
+ export function applyListAwareTextCommand(
54
+ context: StoryMutationContext,
55
+ command: DispatchTextCommand,
56
+ deps: ListAwareDispatchDeps,
57
+ ): ListAwareMutationResult | null {
58
+ const paragraphContext = deps.resolveActiveParagraphContext(context.localSnapshot);
59
+ if (!paragraphContext?.paragraph.numbering) {
60
+ return null;
61
+ }
62
+
63
+ switch (command.type) {
64
+ case "insert-tab": {
65
+ const result = indentListItems(
66
+ context.localDocument,
67
+ [paragraphContext.paragraphIndex],
68
+ { timestamp: context.timestamp },
69
+ );
70
+ return createListMutationResult(result, context.localSnapshot.selection, deps);
71
+ }
72
+ case "outdent-tab": {
73
+ const result = outdentListItems(
74
+ context.localDocument,
75
+ [paragraphContext.paragraphIndex],
76
+ { timestamp: context.timestamp },
77
+ );
78
+ return createListMutationResult(result, context.localSnapshot.selection, deps);
79
+ }
80
+ case "delete-backward": {
81
+ if (!paragraphContext.atParagraphStart || !context.localSnapshot.selection.isCollapsed) {
82
+ return null;
83
+ }
84
+ const result = backspaceAtListStart(
85
+ context.localDocument,
86
+ paragraphContext.paragraphIndex,
87
+ { timestamp: context.timestamp },
88
+ );
89
+ return result.handled
90
+ ? createListMutationResult(result, context.localSnapshot.selection, deps)
91
+ : null;
92
+ }
93
+ case "split-paragraph": {
94
+ if (!context.localSnapshot.selection.isCollapsed || !paragraphContext.isEmpty) {
95
+ return null;
96
+ }
97
+ const result = splitListParagraph(
98
+ context.localDocument,
99
+ paragraphContext.paragraphIndex,
100
+ true,
101
+ { timestamp: context.timestamp },
102
+ );
103
+ return result.action === "split"
104
+ ? null
105
+ : createListMutationResult(result, context.localSnapshot.selection, deps);
106
+ }
107
+ default:
108
+ return null;
109
+ }
110
+ }
111
+
112
+ function createListMutationResult(
113
+ result: {
114
+ document: EditorSessionState["canonicalDocument"];
115
+ affectedParagraphIndexes: number[];
116
+ },
117
+ selection: RuntimeRenderSnapshot["selection"],
118
+ deps: ListAwareDispatchDeps,
119
+ ): ListAwareMutationResult {
120
+ return {
121
+ changed: result.affectedParagraphIndexes.length > 0,
122
+ document: result.document,
123
+ selection: deps.toRuntimeSelectionSnapshot(selection),
124
+ };
125
+ }