@beyondwork/docx-react-component 1.0.36 → 1.0.38
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.
- package/README.md +103 -13
- package/package.json +1 -1
- package/src/api/package-version.ts +13 -0
- package/src/api/public-types.ts +402 -1
- package/src/core/commands/index.ts +18 -1
- package/src/core/commands/section-layout-commands.ts +58 -0
- package/src/core/commands/table-grid.ts +431 -0
- package/src/core/commands/table-structure-commands.ts +815 -55
- package/src/core/selection/mapping.ts +6 -0
- package/src/io/docx-session.ts +24 -9
- package/src/io/export/build-app-properties-xml.ts +88 -0
- package/src/io/export/serialize-comments.ts +6 -1
- package/src/io/export/serialize-footnotes.ts +10 -9
- package/src/io/export/serialize-headers-footers.ts +11 -10
- package/src/io/export/serialize-main-document.ts +328 -50
- package/src/io/export/serialize-numbering.ts +114 -24
- package/src/io/export/serialize-tables.ts +87 -11
- package/src/io/export/table-properties-xml.ts +174 -20
- package/src/io/export/twip.ts +66 -0
- package/src/io/normalize/normalize-text.ts +20 -0
- package/src/io/ooxml/parse-footnotes.ts +62 -1
- package/src/io/ooxml/parse-headers-footers.ts +62 -1
- package/src/io/ooxml/parse-main-document.ts +158 -1
- package/src/io/ooxml/parse-tables.ts +249 -0
- package/src/legal/bookmarks.ts +78 -0
- package/src/model/canonical-document.ts +45 -0
- package/src/review/store/scope-tag-diff.ts +130 -0
- package/src/runtime/document-layout.ts +4 -2
- package/src/runtime/document-navigation.ts +2 -306
- package/src/runtime/document-runtime.ts +287 -11
- package/src/runtime/layout/default-page-format.ts +96 -0
- package/src/runtime/layout/docx-font-loader.ts +143 -0
- package/src/runtime/layout/index.ts +233 -0
- package/src/runtime/layout/inert-layout-facet.ts +59 -0
- package/src/runtime/layout/layout-engine-instance.ts +628 -0
- package/src/runtime/layout/layout-invalidation.ts +257 -0
- package/src/runtime/layout/layout-measurement-provider.ts +175 -0
- package/src/runtime/layout/margin-preset-catalog.ts +178 -0
- package/src/runtime/layout/measurement-backend-canvas.ts +307 -0
- package/src/runtime/layout/measurement-backend-empirical.ts +208 -0
- package/src/runtime/layout/page-format-catalog.ts +233 -0
- package/src/runtime/layout/page-fragment-mapper.ts +179 -0
- package/src/runtime/layout/page-graph.ts +452 -0
- package/src/runtime/layout/page-layout-snapshot-adapter.ts +70 -0
- package/src/runtime/layout/page-story-resolver.ts +195 -0
- package/src/runtime/layout/paginated-layout-engine.ts +921 -0
- package/src/runtime/layout/project-block-fragments.ts +91 -0
- package/src/runtime/layout/public-facet.ts +1398 -0
- package/src/runtime/layout/resolved-formatting-document.ts +317 -0
- package/src/runtime/layout/resolved-formatting-state.ts +430 -0
- package/src/runtime/layout/table-render-plan.ts +229 -0
- package/src/runtime/render/block-fragment-projection.ts +35 -0
- package/src/runtime/render/decoration-resolver.ts +189 -0
- package/src/runtime/render/index.ts +57 -0
- package/src/runtime/render/pending-op-delta-reader.ts +129 -0
- package/src/runtime/render/render-frame-types.ts +317 -0
- package/src/runtime/render/render-kernel.ts +755 -0
- package/src/runtime/scope-tag-registry.ts +95 -0
- package/src/runtime/surface-projection.ts +1 -0
- package/src/runtime/text-ack-range.ts +49 -0
- package/src/runtime/view-state.ts +67 -0
- package/src/runtime/workflow-markup.ts +1 -5
- package/src/runtime/workflow-rail-segments.ts +280 -0
- package/src/ui/WordReviewEditor.tsx +99 -15
- package/src/ui/editor-runtime-boundary.ts +10 -1
- package/src/ui/editor-shell-view.tsx +6 -0
- package/src/ui/editor-surface-controller.tsx +3 -0
- package/src/ui/headless/chrome-registry.ts +501 -0
- package/src/ui/headless/scoped-chrome-policy.ts +183 -0
- package/src/ui/headless/selection-tool-context.ts +2 -0
- package/src/ui/headless/selection-tool-resolver.ts +36 -17
- package/src/ui/headless/selection-tool-types.ts +10 -0
- package/src/ui-tailwind/chrome/chrome-preset-model.ts +23 -2
- package/src/ui-tailwind/chrome/role-action-sets.ts +74 -0
- package/src/ui-tailwind/chrome/tw-detach-handle.tsx +147 -0
- package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +163 -0
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +57 -92
- package/src/ui-tailwind/chrome/tw-selection-tool-placement.ts +149 -0
- package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +15 -4
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +274 -138
- package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +90 -0
- package/src/ui-tailwind/chrome-overlay/index.ts +22 -0
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +86 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +178 -0
- package/src/ui-tailwind/chrome-overlay/tw-workspace-view-switcher.tsx +95 -0
- package/src/ui-tailwind/editor-surface/fast-text-edit-lane.ts +337 -0
- package/src/ui-tailwind/editor-surface/local-edit-session-state.ts +100 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +27 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +20 -2
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +93 -23
- package/src/ui-tailwind/editor-surface/predicted-position-map.ts +78 -0
- package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +63 -0
- package/src/ui-tailwind/editor-surface/predicted-tx-gate.ts +39 -0
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +176 -6
- package/src/ui-tailwind/index.ts +33 -0
- package/src/ui-tailwind/review/tw-comment-sidebar.tsx +2 -2
- package/src/ui-tailwind/review/tw-rail-card.tsx +150 -0
- package/src/ui-tailwind/review/tw-review-rail-footer.tsx +52 -0
- package/src/ui-tailwind/review/tw-review-rail.tsx +166 -11
- package/src/ui-tailwind/review/tw-workflow-tab.tsx +108 -0
- package/src/ui-tailwind/theme/editor-theme.css +505 -144
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +559 -0
- package/src/ui-tailwind/toolbar/tw-scope-posture-menu.tsx +182 -0
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +162 -0
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +2 -2
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +304 -166
- package/src/ui-tailwind/tw-review-workspace.tsx +163 -2
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
summary:
|
|
2
|
+
title: Beyond Work Components
|
|
3
|
+
summary: Backoffice work components landing page and primary router into consumer, wrapper, agent, and maintainer documentation.
|
|
4
4
|
audience: consumer, wrapper, agent, maintainer
|
|
5
5
|
stability: main-path
|
|
6
6
|
docRole: main-path
|
|
7
7
|
canonical: true
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Beyond Work Components
|
|
11
11
|
|
|
12
12
|
[](https://github.com/bwllaming/React-OOXML-Office/actions/workflows/ci.yml)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
This repository builds **backoffice work components** for the [Beyond Work](https://beyondwork.ai) runtime — embeddable, composable modules that handle document editing, review workflows, data processing, and task automation inside enterprise workspaces.
|
|
15
|
+
|
|
16
|
+
The design principle across every component: **advanced tasks should be equally easy for AI agents and human users.** Every capability exposed through the UI is also available through a structured API. Every API is designed so an agent can inspect state, reason about it, and act on it without special accommodation. Humans and agents share the same runtime, the same commands, the same read models, and the same fidelity guarantees.
|
|
15
17
|
|
|
16
18
|
## Use This README For
|
|
17
19
|
|
|
@@ -19,11 +21,70 @@ canonical: true
|
|
|
19
21
|
- installing the package
|
|
20
22
|
- finding the right documentation lane quickly
|
|
21
23
|
|
|
22
|
-
Do not use this README as the full package contract. The canonical consumer path starts in `docs/README.md`, `docs/reference/public-api.md
|
|
24
|
+
Do not use this README as the full package contract. The canonical consumer path starts in `docs/README.md`, [`docs/reference/public-api.md`](docs/reference/public-api.md), and [`docs/reference/integration-guide.md`](docs/reference/integration-guide.md).
|
|
25
|
+
|
|
26
|
+
## Components
|
|
27
|
+
|
|
28
|
+
### Document Editor (`@beyondwork/docx-react-component`)
|
|
29
|
+
|
|
30
|
+
A fidelity-first React `.docx` editor centered on `WordReviewEditor`. Built for legal review, contract negotiation, and any workflow where documents need to survive a round-trip through Microsoft Word without damage.
|
|
31
|
+
|
|
32
|
+
**Capabilities:**
|
|
33
|
+
- Full tracked-change and comment support (add, resolve, accept, reject)
|
|
34
|
+
- Suggesting mode where every edit automatically becomes a tracked change
|
|
35
|
+
- Round-trip OOXML preservation — open, edit, export, reopen in Word without repair prompts
|
|
36
|
+
- Workflow overlays with scope-based editing constraints
|
|
37
|
+
- Runtime-backed read models for document structure, review state, selection, compatibility, and fields
|
|
38
|
+
- Document comparison with LCS-based diffing and redline export
|
|
39
|
+
- Legal document analysis (bookmarks, cross-references, defined terms, signature blocks)
|
|
40
|
+
- Real-time collaboration via Yjs
|
|
41
|
+
|
|
42
|
+
**Human-AI parity in practice:**
|
|
43
|
+
- The human clicks "Add Comment" on selected text; the agent calls `addComment({ anchor, body })` on the same selection
|
|
44
|
+
- The human reviews tracked changes in the sidebar; the agent reads `getTrackedChanges()` and makes the same accept/reject decisions
|
|
45
|
+
- The human exports via toolbar; the agent calls `exportDocx()` after the same `getCompatibilityReport()` check
|
|
46
|
+
- Workflow overlays constrain both humans and agents identically — `getInteractionGuardSnapshot()` is the single source of posture truth
|
|
47
|
+
- The AI action policy module gates 37 discrete agent operations with risk classification and context validation
|
|
48
|
+
|
|
49
|
+
### Workblocks
|
|
50
|
+
|
|
51
|
+
Composable task modules that automate business processes. Each workblock is a self-contained package of Python backend logic, React UI components, and a declarative task graph defined in `manifest.yaml`. They execute on the Beyond Work platform via Temporal workflows.
|
|
52
|
+
|
|
53
|
+
**Categories:**
|
|
54
|
+
- **Document processing** — invoice extraction, PDF template OCR, bulk processing, email-to-action
|
|
55
|
+
- **AI agents** — explore, flow debugging, data querying, task launching, authoring
|
|
56
|
+
- **Analytics** — execution history, company insights, timeline queries
|
|
57
|
+
- **Learning** — human correction capture, learning set curation, embedding management
|
|
58
|
+
- **Infrastructure** — registry, health checks, credential management (9 types)
|
|
59
|
+
|
|
60
|
+
**Human-AI parity in practice:**
|
|
61
|
+
- Users create workblocks through VS Code Studio with prompts and visual editing; authoring agents create them through the same manifest schema and file tools
|
|
62
|
+
- Users validate invoice fields in a React form; agents validate the same fields through typed task inputs/outputs
|
|
63
|
+
- Both humans and agents operate within the same workblock execution engine — same task graph, same data flow, same error handling
|
|
64
|
+
|
|
65
|
+
## The Beyond Work Runtime
|
|
66
|
+
|
|
67
|
+
These components plug into a four-layer platform:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
User-Facing (Layer 4)
|
|
71
|
+
neui (Next.js 15), bport (BFF), MCP server, VS Code extension
|
|
72
|
+
|
|
|
73
|
+
Workblocks (Layer 3)
|
|
74
|
+
20+ composable task modules: agents, data processing, credentials
|
|
75
|
+
|
|
|
76
|
+
Platform Services (Layer 2)
|
|
77
|
+
bworker (Go), modelproxy (LiteLLM), registry, pythonworker, Temporal
|
|
78
|
+
|
|
|
79
|
+
AWS Infrastructure (Layer 1)
|
|
80
|
+
EKS, Crossplane, Terraform, PostgreSQL, Redis, Qdrant, S3, SQS
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The document editor lives at Layer 4 as an embeddable surface. Workblocks live at Layer 3 and are orchestrated by the platform. Both expose their capabilities symmetrically to human UIs and agent APIs.
|
|
23
84
|
|
|
24
85
|
## Current Package Reality
|
|
25
86
|
|
|
26
|
-
The
|
|
87
|
+
The shipped contract today is docx-first:
|
|
27
88
|
|
|
28
89
|
- `docx` is the only implemented and shipped runtime contract
|
|
29
90
|
- `xlsx` is planned work, not part of the current package contract
|
|
@@ -93,11 +154,11 @@ The current shipped ESM exports include:
|
|
|
93
154
|
- `@beyondwork/docx-react-component/tailwind`
|
|
94
155
|
- `@beyondwork/docx-react-component/api/public-types`
|
|
95
156
|
|
|
96
|
-
Use `docs/reference/public-api.md` and `docs/reference/public-api.manifest.json` for the current contract inventory and stability guidance.
|
|
157
|
+
Use [`docs/reference/public-api.md`](docs/reference/public-api.md) and `docs/reference/public-api.manifest.json` for the current contract inventory and stability guidance.
|
|
97
158
|
|
|
98
159
|
## Product Contract
|
|
99
160
|
|
|
100
|
-
For every
|
|
161
|
+
For every component this repo ships, the standard is:
|
|
101
162
|
|
|
102
163
|
> Open -> edit -> save -> reopen in the host application without damage.
|
|
103
164
|
|
|
@@ -158,7 +219,38 @@ Current integration honesty:
|
|
|
158
219
|
|
|
159
220
|
The CCEP corpus is kept on `main` as a maintainer-safe smoke-doc source set for agreement-heavy validation and wrapper or agent benchmarking.
|
|
160
221
|
|
|
161
|
-
|
|
222
|
+
### Technical Wiki
|
|
223
|
+
|
|
224
|
+
- [`docs/wiki/`](docs/wiki/) — Feature-by-feature technical documentation (25+ topics covering OOXML, ProseMirror, runtime, and platform)
|
|
225
|
+
|
|
226
|
+
## Agent Integration
|
|
227
|
+
|
|
228
|
+
Agents consume the editor through a consistent pipeline:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
inspect --> locate --> mutate --> validate --> export
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Beyond Work platform agents extend this with propose/approve gates:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
inspect --> locate --> propose --> approve --> mutate --> validate --> export
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The package exposes purpose-built read models — not a monolithic state dump:
|
|
241
|
+
|
|
242
|
+
| Read model | Getter | Purpose |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| Document surface | `getRenderSnapshot()` | Structure, blocks, text, selection |
|
|
245
|
+
| Comments | `getComments()` | Thread state, resolution, anchors |
|
|
246
|
+
| Tracked changes | `getTrackedChanges()` | Revision inventory, actionability |
|
|
247
|
+
| Workflow scope | `getWorkflowScopeSnapshot()` | Scope boundaries, work items, mode |
|
|
248
|
+
| Interaction guard | `getInteractionGuardSnapshot()` | Effective mode, blocked reasons |
|
|
249
|
+
| Compatibility | `getCompatibilityReport()` | Export risk assessment |
|
|
250
|
+
| Warnings | `getWarnings()` | Active fidelity or mutation warnings |
|
|
251
|
+
| Fields | `getFieldSnapshot()` | Field posture and refresh state |
|
|
252
|
+
|
|
253
|
+
Agents should read the narrow snapshot that answers the next question, not pull the full render snapshot for every decision.
|
|
162
254
|
|
|
163
255
|
## Packaging And Release
|
|
164
256
|
|
|
@@ -181,9 +273,7 @@ Maintainer prompts, operator runbooks, and proof/closure material remain importa
|
|
|
181
273
|
|
|
182
274
|
## Guiding Principle
|
|
183
275
|
|
|
184
|
-
This repo is not
|
|
185
|
-
|
|
186
|
-
It is building fidelity-first office-document runtimes with explicit preservation and calm, reviewable UI.
|
|
276
|
+
This repo builds backoffice work components where humans and AI agents are first-class peers. Every capability is designed for both audiences from the start — not bolted on for one after the other. The result is tools that are powerful enough for complex enterprise workflows and structured enough that an agent can operate them safely and predictably.
|
|
187
277
|
|
|
188
278
|
## Using the package
|
|
189
279
|
|
|
@@ -663,7 +753,7 @@ Fired when the document transitions between clean and dirty (unsaved) states.
|
|
|
663
753
|
|
|
664
754
|
#### `story_changed`
|
|
665
755
|
|
|
666
|
-
Fired when the user navigates between document stories (e.g. main body
|
|
756
|
+
Fired when the user navigates between document stories (e.g. main body -> header/footer).
|
|
667
757
|
|
|
668
758
|
```ts
|
|
669
759
|
{
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.38",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package version string — pinned to package.json `version`.
|
|
3
|
+
*
|
|
4
|
+
* Consumed by export paths that embed a producer identity (e.g.
|
|
5
|
+
* `/docProps/app.xml` `<Application>` tag) so exported packages can be
|
|
6
|
+
* traced back to the exact runtime release.
|
|
7
|
+
*
|
|
8
|
+
* Keep this in lockstep with `package.json#version`. A future enhancement
|
|
9
|
+
* would be to generate this file from package.json at build time; for now
|
|
10
|
+
* the string is committed directly so the runtime works without a build
|
|
11
|
+
* step for tests.
|
|
12
|
+
*/
|
|
13
|
+
export const PACKAGE_VERSION = "1.0.36";
|
package/src/api/public-types.ts
CHANGED
|
@@ -1,4 +1,60 @@
|
|
|
1
1
|
import type { PersistedEditorSnapshot as RuntimePersistedEditorSnapshot } from "../core/state/editor-state.ts";
|
|
2
|
+
import type { WordReviewEditorLayoutFacet } from "../runtime/layout/public-facet.ts";
|
|
3
|
+
|
|
4
|
+
export type {
|
|
5
|
+
WordReviewEditorLayoutFacet,
|
|
6
|
+
LayoutFacetEvent,
|
|
7
|
+
LayoutFacetInvalidationReason,
|
|
8
|
+
PublicBlockFragment,
|
|
9
|
+
PublicBlockMeasurement,
|
|
10
|
+
PublicFieldDirtinessReport,
|
|
11
|
+
PublicLineBox,
|
|
12
|
+
PublicMeasurementFidelity,
|
|
13
|
+
PublicNoteAllocation,
|
|
14
|
+
PublicPageAnchor,
|
|
15
|
+
PublicPageNode,
|
|
16
|
+
PublicPageRegion,
|
|
17
|
+
PublicPageRegions,
|
|
18
|
+
PublicPageSpan,
|
|
19
|
+
PublicResolvedPageStories,
|
|
20
|
+
PublicResolvedParagraphFormatting,
|
|
21
|
+
PublicResolvedRunFormatting,
|
|
22
|
+
PublicSectionNode,
|
|
23
|
+
// R0.5: named page-format + margin-preset catalogs
|
|
24
|
+
PageFormatDefinition,
|
|
25
|
+
ActivePageFormat,
|
|
26
|
+
MarginPresetDefinition,
|
|
27
|
+
ActiveMarginPreset,
|
|
28
|
+
RenderZoomSummary,
|
|
29
|
+
} from "../runtime/layout/public-facet.ts";
|
|
30
|
+
|
|
31
|
+
// R1: render-kernel shapes (frame, decoration index, anchor index) — these
|
|
32
|
+
// are exposed additively so consumers can read the future `getRenderFrame`
|
|
33
|
+
// output without depending on the internal render kernel module.
|
|
34
|
+
export type {
|
|
35
|
+
RenderFrame,
|
|
36
|
+
RenderPage,
|
|
37
|
+
RenderPageRegions,
|
|
38
|
+
RenderStoryRegion,
|
|
39
|
+
RenderBlock,
|
|
40
|
+
RenderLine,
|
|
41
|
+
RenderLineAnchor,
|
|
42
|
+
RenderBlockDecoration,
|
|
43
|
+
RenderFrameRect,
|
|
44
|
+
RenderZoom,
|
|
45
|
+
RenderAnchorIndex,
|
|
46
|
+
RenderAnchorQuery,
|
|
47
|
+
RenderFrameQueryOptions,
|
|
48
|
+
RenderHitResult,
|
|
49
|
+
RenderKernelEvent,
|
|
50
|
+
RenderPoint,
|
|
51
|
+
DecorationIndex,
|
|
52
|
+
PageChromeReservations,
|
|
53
|
+
} from "../runtime/render/index.ts";
|
|
54
|
+
|
|
55
|
+
// R0: scope-rail posture vocabulary and chrome pin state — exposed so
|
|
56
|
+
// host apps can drive the editor role and render custom posture menus.
|
|
57
|
+
export type { ScopeRailPosture } from "../runtime/workflow-rail-segments.ts";
|
|
2
58
|
|
|
3
59
|
export type FieldFamily = import("../model/canonical-document.ts").FieldFamily;
|
|
4
60
|
export type FieldRefreshStatus = import("../model/canonical-document.ts").FieldRefreshStatus;
|
|
@@ -767,6 +823,7 @@ export type SurfaceBlockSnapshot =
|
|
|
767
823
|
keepNext?: boolean;
|
|
768
824
|
keepLines?: boolean;
|
|
769
825
|
pageBreakBefore?: boolean;
|
|
826
|
+
widowControl?: boolean;
|
|
770
827
|
outlineLevel?: number;
|
|
771
828
|
bidi?: boolean;
|
|
772
829
|
suppressLineNumbers?: boolean;
|
|
@@ -1013,9 +1070,231 @@ export interface TableStructureContextSnapshot {
|
|
|
1013
1070
|
mergeCells: TableOperationCapabilitySnapshot;
|
|
1014
1071
|
splitCell: TableOperationCapabilitySnapshot;
|
|
1015
1072
|
deleteTable: TableOperationCapabilitySnapshot;
|
|
1073
|
+
// P2g — table-level authoring ops
|
|
1074
|
+
setTableWidth: TableOperationCapabilitySnapshot;
|
|
1075
|
+
setTableAlignment: TableOperationCapabilitySnapshot;
|
|
1076
|
+
setTableIndent: TableOperationCapabilitySnapshot;
|
|
1077
|
+
setTableLayoutMode: TableOperationCapabilitySnapshot;
|
|
1078
|
+
setTableCellMargins: TableOperationCapabilitySnapshot;
|
|
1079
|
+
setTableBorders: TableOperationCapabilitySnapshot;
|
|
1080
|
+
setTableCaption: TableOperationCapabilitySnapshot;
|
|
1081
|
+
setTableDescription: TableOperationCapabilitySnapshot;
|
|
1082
|
+
// P2h — column / row sizing + row props
|
|
1083
|
+
setColumnWidth: TableOperationCapabilitySnapshot;
|
|
1084
|
+
distributeColumnsEvenly: TableOperationCapabilitySnapshot;
|
|
1085
|
+
setRowHeight: TableOperationCapabilitySnapshot;
|
|
1086
|
+
setRowCantSplit: TableOperationCapabilitySnapshot;
|
|
1087
|
+
setRowIsHeader: TableOperationCapabilitySnapshot;
|
|
1088
|
+
setRowAlignment: TableOperationCapabilitySnapshot;
|
|
1089
|
+
insertRows: TableOperationCapabilitySnapshot;
|
|
1090
|
+
insertColumns: TableOperationCapabilitySnapshot;
|
|
1091
|
+
// P2i — cell-level ops (over a locator)
|
|
1092
|
+
setCellBorders: TableOperationCapabilitySnapshot;
|
|
1093
|
+
setCellShading: TableOperationCapabilitySnapshot;
|
|
1094
|
+
clearCellShading: TableOperationCapabilitySnapshot;
|
|
1095
|
+
setCellMargins: TableOperationCapabilitySnapshot;
|
|
1096
|
+
setCellVerticalAlign: TableOperationCapabilitySnapshot;
|
|
1097
|
+
setCellTextDirection: TableOperationCapabilitySnapshot;
|
|
1098
|
+
setCellNoWrap: TableOperationCapabilitySnapshot;
|
|
1099
|
+
setCellFitText: TableOperationCapabilitySnapshot;
|
|
1016
1100
|
};
|
|
1017
1101
|
}
|
|
1018
1102
|
|
|
1103
|
+
// ─── Table typed-op surface (P2.5) ───────────────────────────────────────────
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* Width/height unit used by OOXML table properties.
|
|
1107
|
+
*/
|
|
1108
|
+
export interface PublicTableWidth {
|
|
1109
|
+
value: number;
|
|
1110
|
+
type: "dxa" | "auto" | "pct" | "nil";
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Reusable border-spec shape for table-level and cell-level borders.
|
|
1115
|
+
* Matches OOXML w:*Borders child attributes.
|
|
1116
|
+
*/
|
|
1117
|
+
export interface PublicBorderSpec {
|
|
1118
|
+
value?: string;
|
|
1119
|
+
size?: number;
|
|
1120
|
+
space?: number;
|
|
1121
|
+
color?: string;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
export interface PublicTableBorders {
|
|
1125
|
+
top?: PublicBorderSpec;
|
|
1126
|
+
left?: PublicBorderSpec;
|
|
1127
|
+
bottom?: PublicBorderSpec;
|
|
1128
|
+
right?: PublicBorderSpec;
|
|
1129
|
+
insideH?: PublicBorderSpec;
|
|
1130
|
+
insideV?: PublicBorderSpec;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
export interface PublicTableCellBorders {
|
|
1134
|
+
top?: PublicBorderSpec;
|
|
1135
|
+
left?: PublicBorderSpec;
|
|
1136
|
+
bottom?: PublicBorderSpec;
|
|
1137
|
+
right?: PublicBorderSpec;
|
|
1138
|
+
insideH?: PublicBorderSpec;
|
|
1139
|
+
insideV?: PublicBorderSpec;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
export interface PublicTableCellMargins {
|
|
1143
|
+
top?: number;
|
|
1144
|
+
left?: number;
|
|
1145
|
+
bottom?: number;
|
|
1146
|
+
right?: number;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
export interface PublicCellShading {
|
|
1150
|
+
fill?: string;
|
|
1151
|
+
color?: string;
|
|
1152
|
+
val?: string;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Addresses a cell (or set of cells) for locator-driven cell-level ops.
|
|
1157
|
+
*
|
|
1158
|
+
* - `anchor`: the currently anchored cell from the active selection
|
|
1159
|
+
* - `index`: explicit (rowIndex, columnIndex)
|
|
1160
|
+
* - `rect`: rectangular range in logical grid coordinates
|
|
1161
|
+
* - `row` / `column`: all cells in a single row or column
|
|
1162
|
+
* - `selection`: whatever the active selection covers
|
|
1163
|
+
*/
|
|
1164
|
+
export type PublicCellLocator =
|
|
1165
|
+
| { kind: "anchor" }
|
|
1166
|
+
| { kind: "index"; rowIndex: number; columnIndex: number }
|
|
1167
|
+
| {
|
|
1168
|
+
kind: "rect";
|
|
1169
|
+
rect: { top: number; left: number; bottom: number; right: number };
|
|
1170
|
+
}
|
|
1171
|
+
| { kind: "row"; rowIndex: number }
|
|
1172
|
+
| { kind: "column"; columnIndex: number }
|
|
1173
|
+
| { kind: "selection" };
|
|
1174
|
+
|
|
1175
|
+
/**
|
|
1176
|
+
* Discriminated union of every table operation the public API exposes.
|
|
1177
|
+
* Mirrors the internal `TableStructureOperation` variants on a stable
|
|
1178
|
+
* kebab-case `kind` discriminator.
|
|
1179
|
+
*
|
|
1180
|
+
* Stability: additive. New ops land as new `kind` values; existing
|
|
1181
|
+
* variants keep the same shape across minor versions.
|
|
1182
|
+
*/
|
|
1183
|
+
export type TableOp =
|
|
1184
|
+
| { kind: "insert"; rows: number; columns: number }
|
|
1185
|
+
| { kind: "delete-table" }
|
|
1186
|
+
| { kind: "add-row-before" }
|
|
1187
|
+
| { kind: "add-row-after" }
|
|
1188
|
+
| { kind: "add-column-before" }
|
|
1189
|
+
| { kind: "add-column-after" }
|
|
1190
|
+
| { kind: "delete-row" }
|
|
1191
|
+
| { kind: "delete-column" }
|
|
1192
|
+
| { kind: "merge-cells" }
|
|
1193
|
+
| { kind: "split-cell" }
|
|
1194
|
+
| { kind: "set-cell-background"; color: string }
|
|
1195
|
+
// Table-level (P2g)
|
|
1196
|
+
| { kind: "set-table-width"; width: PublicTableWidth }
|
|
1197
|
+
| { kind: "set-table-alignment"; alignment: "left" | "center" | "right" }
|
|
1198
|
+
| { kind: "set-table-indent"; indent: PublicTableWidth }
|
|
1199
|
+
| { kind: "set-table-layout-mode"; mode: "fixed" | "autofit" }
|
|
1200
|
+
| { kind: "set-table-cell-margins"; margins: Partial<PublicTableCellMargins> }
|
|
1201
|
+
| { kind: "set-table-borders"; borders: Partial<PublicTableBorders> }
|
|
1202
|
+
| { kind: "set-table-style"; styleId: string | null }
|
|
1203
|
+
| { kind: "set-table-caption"; caption: string | null }
|
|
1204
|
+
| { kind: "set-table-description"; description: string | null }
|
|
1205
|
+
// Column / row sizing + row props (P2h)
|
|
1206
|
+
| { kind: "set-column-width"; columnIndex: number; twips: number }
|
|
1207
|
+
| {
|
|
1208
|
+
kind: "distribute-columns-evenly";
|
|
1209
|
+
columnRange?: { from: number; to: number };
|
|
1210
|
+
}
|
|
1211
|
+
| {
|
|
1212
|
+
kind: "set-row-height";
|
|
1213
|
+
rowIndex: number;
|
|
1214
|
+
twips: number;
|
|
1215
|
+
rule: "auto" | "atLeast" | "exact";
|
|
1216
|
+
}
|
|
1217
|
+
| { kind: "set-row-cant-split"; rowIndex: number; value: boolean }
|
|
1218
|
+
| { kind: "set-row-is-header"; rowIndex: number; value: boolean }
|
|
1219
|
+
| {
|
|
1220
|
+
kind: "set-row-alignment";
|
|
1221
|
+
rowIndex: number;
|
|
1222
|
+
alignment: "left" | "center" | "right";
|
|
1223
|
+
}
|
|
1224
|
+
| {
|
|
1225
|
+
kind: "insert-rows";
|
|
1226
|
+
rowIndex: number;
|
|
1227
|
+
at: "before" | "after";
|
|
1228
|
+
count: number;
|
|
1229
|
+
}
|
|
1230
|
+
| {
|
|
1231
|
+
kind: "insert-columns";
|
|
1232
|
+
columnIndex: number;
|
|
1233
|
+
at: "before" | "after";
|
|
1234
|
+
count: number;
|
|
1235
|
+
widths?: readonly number[];
|
|
1236
|
+
}
|
|
1237
|
+
// Cell-level (P2i)
|
|
1238
|
+
| {
|
|
1239
|
+
kind: "set-cell-borders";
|
|
1240
|
+
locator: PublicCellLocator;
|
|
1241
|
+
borders: Partial<PublicTableCellBorders>;
|
|
1242
|
+
}
|
|
1243
|
+
| {
|
|
1244
|
+
kind: "set-cell-shading";
|
|
1245
|
+
locator: PublicCellLocator;
|
|
1246
|
+
shading: Partial<PublicCellShading> | null;
|
|
1247
|
+
}
|
|
1248
|
+
| { kind: "clear-cell-shading"; locator: PublicCellLocator }
|
|
1249
|
+
| {
|
|
1250
|
+
kind: "set-cell-margins";
|
|
1251
|
+
locator: PublicCellLocator;
|
|
1252
|
+
margins: Partial<PublicTableCellMargins>;
|
|
1253
|
+
}
|
|
1254
|
+
| {
|
|
1255
|
+
kind: "set-cell-vertical-align";
|
|
1256
|
+
locator: PublicCellLocator;
|
|
1257
|
+
align: "top" | "center" | "bottom";
|
|
1258
|
+
}
|
|
1259
|
+
| {
|
|
1260
|
+
kind: "set-cell-text-direction";
|
|
1261
|
+
locator: PublicCellLocator;
|
|
1262
|
+
direction: "lrTb" | "tbRl" | "btLr";
|
|
1263
|
+
}
|
|
1264
|
+
| { kind: "set-cell-no-wrap"; locator: PublicCellLocator; value: boolean }
|
|
1265
|
+
| { kind: "set-cell-fit-text"; locator: PublicCellLocator; value: boolean };
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* Outcome of `ref.tables.apply(op)`.
|
|
1269
|
+
*/
|
|
1270
|
+
export interface TableOpResult {
|
|
1271
|
+
/** Whether the op mutated canonical document state. */
|
|
1272
|
+
changed: boolean;
|
|
1273
|
+
/**
|
|
1274
|
+
* When the op was refused (e.g. no table selection, merge not clean),
|
|
1275
|
+
* a short human-readable reason. `null` when the op committed.
|
|
1276
|
+
*/
|
|
1277
|
+
coercedReason: string | null;
|
|
1278
|
+
/**
|
|
1279
|
+
* Fresh capability snapshot post-op. `null` when there is no table in
|
|
1280
|
+
* the current selection.
|
|
1281
|
+
*/
|
|
1282
|
+
capabilities: TableStructureContextSnapshot | null;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* The `tables` property on `WordReviewEditorRef`. Minimal surface in this
|
|
1287
|
+
* phase: a typed dispatch boundary for every table op plus a capability
|
|
1288
|
+
* read. Read-only geometry queries (columns, rows, render plan, ...)
|
|
1289
|
+
* land with the layout engine + render kernel integration.
|
|
1290
|
+
*/
|
|
1291
|
+
export interface WordReviewEditorTablesFacet {
|
|
1292
|
+
/** Dispatch a typed table op through the runtime. */
|
|
1293
|
+
apply(op: TableOp): TableOpResult;
|
|
1294
|
+
/** Current capability snapshot for the active table selection. */
|
|
1295
|
+
getCapabilities(): TableStructureContextSnapshot | null;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1019
1298
|
export interface PageRegionHitTest {
|
|
1020
1299
|
region: "body" | "header" | "footer" | "margin" | "gutter";
|
|
1021
1300
|
sectionIndex: number;
|
|
@@ -1044,8 +1323,50 @@ export interface EditorViewStateSnapshot {
|
|
|
1044
1323
|
activeObjectFrame: LayoutMeasurement["objectFrame"] | null;
|
|
1045
1324
|
measurement: LayoutMeasurement;
|
|
1046
1325
|
isFocused: boolean;
|
|
1326
|
+
/**
|
|
1327
|
+
* Role-scoped chrome dimension (spec §6.4). Drives which action set the
|
|
1328
|
+
* top toolbar renders: `"editor"` exposes authoring (insert, format,
|
|
1329
|
+
* Mark-section menu, tracked-changes toggle), `"review"` exposes review
|
|
1330
|
+
* queue nav + accept/reject, `"workflow"` exposes work-item traversal.
|
|
1331
|
+
* Independent of `viewMode` / `documentMode`.
|
|
1332
|
+
*/
|
|
1333
|
+
editorRole: EditorRole;
|
|
1334
|
+
/**
|
|
1335
|
+
* Pin state for detachable chrome surfaces — topnav and the selection
|
|
1336
|
+
* tier tool. Absent key means "docked default"; `detached: true` means
|
|
1337
|
+
* the surface renders as a floating, user-positioned panel. State is
|
|
1338
|
+
* runtime-owned, per-session, and survives snapshot rebuilds.
|
|
1339
|
+
*/
|
|
1340
|
+
chromePins: ChromePinsState;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Role-scoped chrome dimension (spec §6.4 of runtime-rendering-and-chrome-phase.md).
|
|
1345
|
+
*
|
|
1346
|
+
* - `"editor"` — authoring posture. Toolbar surfaces format, insert menu,
|
|
1347
|
+
* Mark-section posture menu, tracked-changes display toggle, comment.
|
|
1348
|
+
* - `"review"` — reviewing posture. Toolbar surfaces prev/next, accept,
|
|
1349
|
+
* reject, accept-all / reject-all in scope, markup mode, comment.
|
|
1350
|
+
* - `"workflow"` — workflow-actor posture. Toolbar surfaces prev/next
|
|
1351
|
+
* work item, claim, skip, mark complete, mark blocked, jump to scope.
|
|
1352
|
+
*/
|
|
1353
|
+
export type EditorRole = "editor" | "review" | "workflow";
|
|
1354
|
+
|
|
1355
|
+
/**
|
|
1356
|
+
* Chrome surfaces that can be detached into a floating, draggable panel.
|
|
1357
|
+
* Extend this union as new surfaces adopt the `DraggableFloat` primitive.
|
|
1358
|
+
*/
|
|
1359
|
+
export type ChromePinSurface = "topnav" | "selectionTier";
|
|
1360
|
+
|
|
1361
|
+
export interface PinState {
|
|
1362
|
+
/** True when the surface is detached from its default dock. */
|
|
1363
|
+
detached: boolean;
|
|
1364
|
+
/** User-chosen offset in CSS px from the surface's dock origin. */
|
|
1365
|
+
offset: { x: number; y: number };
|
|
1047
1366
|
}
|
|
1048
1367
|
|
|
1368
|
+
export type ChromePinsState = Partial<Record<ChromePinSurface, PinState>>;
|
|
1369
|
+
|
|
1049
1370
|
export interface CommandStateSnapshot {
|
|
1050
1371
|
canUndo: boolean;
|
|
1051
1372
|
canRedo: boolean;
|
|
@@ -1916,13 +2237,46 @@ export interface WordReviewEditorRef {
|
|
|
1916
2237
|
getRuntimeContextAnalytics(
|
|
1917
2238
|
query?: RuntimeContextAnalyticsQuery,
|
|
1918
2239
|
): RuntimeContextAnalyticsSnapshot | null;
|
|
2240
|
+
|
|
2241
|
+
/**
|
|
2242
|
+
* Runtime-owned layout facet.
|
|
2243
|
+
*
|
|
2244
|
+
* The ergonomic surface for walking the page graph, resolving offsets to
|
|
2245
|
+
* fragments, inspecting formatting, and observing layout events. Prefer
|
|
2246
|
+
* this over `getPageLayoutSnapshot()` / `getDocumentNavigationSnapshot()`
|
|
2247
|
+
* for new code — those remain as thin adapters for compatibility.
|
|
2248
|
+
*
|
|
2249
|
+
* Returns `null` only when the runtime is still loading; once the `ready`
|
|
2250
|
+
* event has fired, the facet is always available.
|
|
2251
|
+
*/
|
|
2252
|
+
readonly layout: WordReviewEditorLayoutFacet;
|
|
2253
|
+
/**
|
|
2254
|
+
* Typed dispatch boundary for every table operation the runtime
|
|
2255
|
+
* supports. Existing flat verbs (`addRowBefore`, `setCellBackground`,
|
|
2256
|
+
* …) remain as compatibility wrappers; new ops land through
|
|
2257
|
+
* `ref.tables.apply(op)` with a typed discriminated union.
|
|
2258
|
+
*/
|
|
2259
|
+
readonly tables: WordReviewEditorTablesFacet;
|
|
1919
2260
|
}
|
|
1920
2261
|
|
|
2262
|
+
/**
|
|
2263
|
+
* Density + role-scoped chrome preset.
|
|
2264
|
+
*
|
|
2265
|
+
* Historically a pure density knob (`selection` → `simple` → `advanced` →
|
|
2266
|
+
* `review` progressively exposed more chrome). `"workflow"` was added in
|
|
2267
|
+
* chrome-phase R1 to surface workflow-actor primary actions (prev/next
|
|
2268
|
+
* work item, claim, skip, mark complete, jump to scope) inline in the
|
|
2269
|
+
* top toolbar. Host apps that already use `chromePreset` keep working
|
|
2270
|
+
* unchanged; consumers that want the new workflow view set the preset
|
|
2271
|
+
* to `"workflow"`. For finer-grained role control independent of
|
|
2272
|
+
* density, set `editorRole` on the view state directly.
|
|
2273
|
+
*/
|
|
1921
2274
|
export type WordReviewEditorChromePreset =
|
|
1922
2275
|
| "selection"
|
|
1923
2276
|
| "simple"
|
|
1924
2277
|
| "advanced"
|
|
1925
|
-
| "review"
|
|
2278
|
+
| "review"
|
|
2279
|
+
| "workflow";
|
|
1926
2280
|
|
|
1927
2281
|
export interface WordReviewEditorChromeOptions {
|
|
1928
2282
|
showReviewQueueBar: boolean;
|
|
@@ -1970,3 +2324,50 @@ export interface WordReviewEditorChromeVisibility {
|
|
|
1970
2324
|
statusBar: boolean;
|
|
1971
2325
|
reviewRail: boolean;
|
|
1972
2326
|
}
|
|
2327
|
+
|
|
2328
|
+
// ---------------------------------------------------------------------------
|
|
2329
|
+
// Bounded local-first predicted-text lane contract
|
|
2330
|
+
// ---------------------------------------------------------------------------
|
|
2331
|
+
|
|
2332
|
+
export type TextCommandAckKind =
|
|
2333
|
+
| "equivalent"
|
|
2334
|
+
| "adjusted"
|
|
2335
|
+
| "rejected"
|
|
2336
|
+
| "structural-divergence";
|
|
2337
|
+
|
|
2338
|
+
export interface ScopeTagTouch {
|
|
2339
|
+
/** Tag family: "comment" | "revision" | "field" | "bookmark" | "sdt" | "opaque" | custom string. */
|
|
2340
|
+
tagType: string;
|
|
2341
|
+
tagId: string;
|
|
2342
|
+
behavior: "extended" | "trimmed" | "split" | "detached" | "unchanged";
|
|
2343
|
+
range: { from: number; to: number };
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
/**
|
|
2347
|
+
* Sync reconciliation result returned by `DocumentRuntime.applyActiveStoryTextCommand`.
|
|
2348
|
+
*
|
|
2349
|
+
* The predicted-text lane in the mounted editor dispatches a local PM transaction,
|
|
2350
|
+
* then calls the runtime synchronously. The ack tells the lane how to reconcile:
|
|
2351
|
+
*
|
|
2352
|
+
* - `equivalent`: runtime accepted the edit and produced the same text shape;
|
|
2353
|
+
* the lane can skip the Lane A PM rebuild entirely.
|
|
2354
|
+
* - `adjusted`: runtime accepted but normalized or added review marks; the lane
|
|
2355
|
+
* patches the affected range from the canonical snapshot.
|
|
2356
|
+
* - `rejected`: runtime blocked the edit (workflow, protection, read-only);
|
|
2357
|
+
* the lane rolls back the predicted PM range from its pre-image.
|
|
2358
|
+
* - `structural-divergence`: the command affected structure beyond the
|
|
2359
|
+
* predicted range; the lane falls back to a full PM rebuild.
|
|
2360
|
+
*/
|
|
2361
|
+
export interface TextCommandAck {
|
|
2362
|
+
kind: TextCommandAckKind;
|
|
2363
|
+
/** Opaque id echoed back from the predicted op. Undefined for canonical callers. */
|
|
2364
|
+
opId?: string;
|
|
2365
|
+
/** Revision token of the document AFTER commit. Empty string when `kind === "rejected"`. */
|
|
2366
|
+
newRevisionToken: string;
|
|
2367
|
+
/** For `adjusted`: the canonical range that differs from the prediction. */
|
|
2368
|
+
adjustedRange?: { fromRuntime: number; toRuntime: number };
|
|
2369
|
+
/** For `rejected`: the blocked reasons. */
|
|
2370
|
+
blockedReasons?: readonly { code: string; message: string }[];
|
|
2371
|
+
/** Tag touches the runtime applied so the lane can redraw decorations without a PM rebuild. */
|
|
2372
|
+
scopeTagTouches?: readonly ScopeTagTouch[];
|
|
2373
|
+
}
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
} from "./text-commands.ts";
|
|
36
36
|
import type { RevisionRecord as CanonicalRevisionRecord } from "../../model/canonical-document.ts";
|
|
37
37
|
import { remapCommentThreads } from "../../review/store/comment-remapping.ts";
|
|
38
|
+
import { collectScopeTagTouches } from "../../review/store/scope-tag-diff.ts";
|
|
38
39
|
import { applyRevisionRuntimeCommand } from "../../runtime/revision-runtime.ts";
|
|
39
40
|
import type { RevisionStore } from "../../review/store/revision-store.ts";
|
|
40
41
|
|
|
@@ -878,6 +879,22 @@ function applyTextCommand(
|
|
|
878
879
|
result.mapping,
|
|
879
880
|
);
|
|
880
881
|
|
|
882
|
+
const scopeTagTouches = collectScopeTagTouches(
|
|
883
|
+
state.document.review.comments,
|
|
884
|
+
reviewState.document.review.comments,
|
|
885
|
+
state.document.review.revisions,
|
|
886
|
+
reviewState.document.review.revisions,
|
|
887
|
+
);
|
|
888
|
+
const mappingWithTouches: TransactionMapping = scopeTagTouches.length > 0
|
|
889
|
+
? {
|
|
890
|
+
...result.mapping,
|
|
891
|
+
metadata: {
|
|
892
|
+
...(result.mapping.metadata ?? {}),
|
|
893
|
+
scopeTagTouches,
|
|
894
|
+
},
|
|
895
|
+
}
|
|
896
|
+
: result.mapping;
|
|
897
|
+
|
|
881
898
|
return createTransaction(
|
|
882
899
|
{
|
|
883
900
|
...state,
|
|
@@ -892,7 +909,7 @@ function applyTextCommand(
|
|
|
892
909
|
{
|
|
893
910
|
historyBoundary: "push",
|
|
894
911
|
markDirty: true,
|
|
895
|
-
mapping:
|
|
912
|
+
mapping: mappingWithTouches,
|
|
896
913
|
effects: reviewState.effects,
|
|
897
914
|
},
|
|
898
915
|
);
|