@usejunior/docx-core 0.9.1 → 0.10.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/atomizer.d.ts +15 -1
- package/dist/atomizer.d.ts.map +1 -1
- package/dist/atomizer.js +37 -1
- package/dist/atomizer.js.map +1 -1
- package/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -1
- package/dist/baselines/atomizer/documentReconstructor.js +218 -90
- package/dist/baselines/atomizer/documentReconstructor.js.map +1 -1
- package/dist/baselines/atomizer/formattingFidelity.d.ts +99 -0
- package/dist/baselines/atomizer/formattingFidelity.d.ts.map +1 -0
- package/dist/baselines/atomizer/formattingFidelity.js +449 -0
- package/dist/baselines/atomizer/formattingFidelity.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-bookmarks.d.ts +37 -0
- package/dist/baselines/atomizer/inPlaceModifier-bookmarks.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-bookmarks.js +189 -0
- package/dist/baselines/atomizer/inPlaceModifier-bookmarks.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-containers.d.ts +74 -0
- package/dist/baselines/atomizer/inPlaceModifier-containers.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-containers.js +171 -0
- package/dist/baselines/atomizer/inPlaceModifier-containers.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-deletion.d.ts +88 -0
- package/dist/baselines/atomizer/inPlaceModifier-deletion.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-deletion.js +326 -0
- package/dist/baselines/atomizer/inPlaceModifier-deletion.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-postprocess.d.ts +85 -0
- package/dist/baselines/atomizer/inPlaceModifier-postprocess.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-postprocess.js +402 -0
- package/dist/baselines/atomizer/inPlaceModifier-postprocess.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-presplit.d.ts +39 -0
- package/dist/baselines/atomizer/inPlaceModifier-presplit.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-presplit.js +265 -0
- package/dist/baselines/atomizer/inPlaceModifier-presplit.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-shared.d.ts +62 -0
- package/dist/baselines/atomizer/inPlaceModifier-shared.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-shared.js +139 -0
- package/dist/baselines/atomizer/inPlaceModifier-shared.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.d.ts +189 -0
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.js +427 -0
- package/dist/baselines/atomizer/inPlaceModifier-wrappers.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier.d.ts +6 -290
- package/dist/baselines/atomizer/inPlaceModifier.d.ts.map +1 -1
- package/dist/baselines/atomizer/inPlaceModifier.js +23 -1828
- package/dist/baselines/atomizer/inPlaceModifier.js.map +1 -1
- package/dist/baselines/atomizer/pipeline.d.ts +76 -1
- package/dist/baselines/atomizer/pipeline.d.ts.map +1 -1
- package/dist/baselines/atomizer/pipeline.js +204 -27
- package/dist/baselines/atomizer/pipeline.js.map +1 -1
- package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -1
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js +56 -160
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -1
- package/dist/compare-types.d.ts +151 -0
- package/dist/compare-types.d.ts.map +1 -0
- package/dist/compare-types.js +2 -0
- package/dist/compare-types.js.map +1 -0
- package/dist/core-types.d.ts +5 -1
- package/dist/core-types.d.ts.map +1 -1
- package/dist/core-types.js +5 -1
- package/dist/core-types.js.map +1 -1
- package/dist/footnotes.d.ts +8 -3
- package/dist/footnotes.d.ts.map +1 -1
- package/dist/footnotes.js +8 -3
- package/dist/footnotes.js.map +1 -1
- package/dist/index.d.ts +6 -150
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/libreoffice-oracle.d.ts +41 -0
- package/dist/integration/libreoffice-oracle.d.ts.map +1 -0
- package/dist/integration/libreoffice-oracle.js +282 -0
- package/dist/integration/libreoffice-oracle.js.map +1 -0
- package/dist/primitives/accept_changes.d.ts +2 -2
- package/dist/primitives/accept_changes.d.ts.map +1 -1
- package/dist/primitives/accept_changes.js +24 -79
- package/dist/primitives/accept_changes.js.map +1 -1
- package/dist/primitives/comments.d.ts +12 -3
- package/dist/primitives/comments.d.ts.map +1 -1
- package/dist/primitives/comments.js +374 -97
- package/dist/primitives/comments.js.map +1 -1
- package/dist/primitives/content_fingerprint.d.ts +29 -0
- package/dist/primitives/content_fingerprint.d.ts.map +1 -0
- package/dist/primitives/content_fingerprint.js +63 -0
- package/dist/primitives/content_fingerprint.js.map +1 -0
- package/dist/primitives/document.d.ts +56 -15
- package/dist/primitives/document.d.ts.map +1 -1
- package/dist/primitives/document.js +303 -32
- package/dist/primitives/document.js.map +1 -1
- package/dist/primitives/document_view-comments.d.ts +18 -0
- package/dist/primitives/document_view-comments.d.ts.map +1 -0
- package/dist/primitives/document_view-comments.js +159 -0
- package/dist/primitives/document_view-comments.js.map +1 -0
- package/dist/primitives/document_view-headings.d.ts +45 -0
- package/dist/primitives/document_view-headings.d.ts.map +1 -0
- package/dist/primitives/document_view-headings.js +247 -0
- package/dist/primitives/document_view-headings.js.map +1 -0
- package/dist/primitives/document_view-styles.d.ts +11 -0
- package/dist/primitives/document_view-styles.d.ts.map +1 -0
- package/dist/primitives/document_view-styles.js +104 -0
- package/dist/primitives/document_view-styles.js.map +1 -0
- package/dist/primitives/document_view-toon.d.ts +37 -0
- package/dist/primitives/document_view-toon.d.ts.map +1 -0
- package/dist/primitives/document_view-toon.js +199 -0
- package/dist/primitives/document_view-toon.js.map +1 -0
- package/dist/primitives/document_view-types.d.ts +137 -0
- package/dist/primitives/document_view-types.d.ts.map +1 -0
- package/dist/primitives/document_view-types.js +2 -0
- package/dist/primitives/document_view-types.js.map +1 -0
- package/dist/primitives/document_view.d.ts +8 -106
- package/dist/primitives/document_view.d.ts.map +1 -1
- package/dist/primitives/document_view.js +134 -301
- package/dist/primitives/document_view.js.map +1 -1
- package/dist/primitives/dom-helpers.d.ts +9 -0
- package/dist/primitives/dom-helpers.d.ts.map +1 -1
- package/dist/primitives/dom-helpers.js +10 -1
- package/dist/primitives/dom-helpers.js.map +1 -1
- package/dist/primitives/footnotes.d.ts +4 -3
- package/dist/primitives/footnotes.d.ts.map +1 -1
- package/dist/primitives/footnotes.js +232 -44
- package/dist/primitives/footnotes.js.map +1 -1
- package/dist/primitives/formatting_tags.d.ts +6 -0
- package/dist/primitives/formatting_tags.d.ts.map +1 -1
- package/dist/primitives/formatting_tags.js +6 -1
- package/dist/primitives/formatting_tags.js.map +1 -1
- package/dist/primitives/index.d.ts +6 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +5 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/layout.d.ts +4 -3
- package/dist/primitives/layout.d.ts.map +1 -1
- package/dist/primitives/layout.js +32 -3
- package/dist/primitives/layout.js.map +1 -1
- package/dist/primitives/merge_runs.d.ts +21 -3
- package/dist/primitives/merge_runs.d.ts.map +1 -1
- package/dist/primitives/merge_runs.js +32 -10
- package/dist/primitives/merge_runs.js.map +1 -1
- package/dist/primitives/namespaces.d.ts +6 -0
- package/dist/primitives/namespaces.d.ts.map +1 -1
- package/dist/primitives/namespaces.js +9 -0
- package/dist/primitives/namespaces.js.map +1 -1
- package/dist/primitives/reject_changes.d.ts +2 -2
- package/dist/primitives/reject_changes.d.ts.map +1 -1
- package/dist/primitives/reject_changes.js +24 -81
- package/dist/primitives/reject_changes.js.map +1 -1
- package/dist/primitives/semantic_tags.d.ts +7 -0
- package/dist/primitives/semantic_tags.d.ts.map +1 -1
- package/dist/primitives/semantic_tags.js +21 -3
- package/dist/primitives/semantic_tags.js.map +1 -1
- package/dist/primitives/serialize_html.d.ts +36 -0
- package/dist/primitives/serialize_html.d.ts.map +1 -0
- package/dist/primitives/serialize_html.js +393 -0
- package/dist/primitives/serialize_html.js.map +1 -0
- package/dist/primitives/serialize_markdown.d.ts +16 -0
- package/dist/primitives/serialize_markdown.d.ts.map +1 -0
- package/dist/primitives/serialize_markdown.js +300 -0
- package/dist/primitives/serialize_markdown.js.map +1 -0
- package/dist/primitives/serialize_plaintext.d.ts +15 -0
- package/dist/primitives/serialize_plaintext.d.ts.map +1 -0
- package/dist/primitives/serialize_plaintext.js +154 -0
- package/dist/primitives/serialize_plaintext.js.map +1 -0
- package/dist/primitives/styles.js +22 -22
- package/dist/primitives/styles.js.map +1 -1
- package/dist/primitives/tables.d.ts.map +1 -1
- package/dist/primitives/tables.js +13 -3
- package/dist/primitives/tables.js.map +1 -1
- package/dist/primitives/text.d.ts +2 -1
- package/dist/primitives/text.d.ts.map +1 -1
- package/dist/primitives/text.js +116 -12
- package/dist/primitives/text.js.map +1 -1
- package/dist/primitives/track-changes-emitter.d.ts +139 -0
- package/dist/primitives/track-changes-emitter.d.ts.map +1 -0
- package/dist/primitives/track-changes-emitter.js +241 -0
- package/dist/primitives/track-changes-emitter.js.map +1 -0
- package/dist/primitives/xml-helpers.d.ts +29 -0
- package/dist/primitives/xml-helpers.d.ts.map +1 -0
- package/dist/primitives/xml-helpers.js +35 -0
- package/dist/primitives/xml-helpers.js.map +1 -0
- package/dist/shared/ooxml/namespaces.d.ts +4 -1
- package/dist/shared/ooxml/namespaces.d.ts.map +1 -1
- package/dist/shared/ooxml/namespaces.js +4 -1
- package/dist/shared/ooxml/namespaces.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-Place AST Modifier
|
|
3
|
+
*
|
|
4
|
+
* Modifies the revised document's AST in-place to add track changes markup.
|
|
5
|
+
* This replaces the reconstruction-based approach with direct tree manipulation.
|
|
6
|
+
*/
|
|
7
|
+
import { CorrelationStatus } from '../../core-types.js';
|
|
8
|
+
import { getDirectContentElements, splitRunAtVisibleOffset, visibleLengthForEl } from '../../primitives/index.js';
|
|
9
|
+
import { warn } from './debug.js';
|
|
10
|
+
import { FIELD_CHAR_TAG_NAMES } from './inPlaceModifier-deletion.js';
|
|
11
|
+
export function atomContentVisibleLength(el) {
|
|
12
|
+
const tag = el.tagName;
|
|
13
|
+
if (tag === 'w:t')
|
|
14
|
+
return (el.textContent ?? '').length;
|
|
15
|
+
if (tag === 'w:tab' || tag === 'w:br')
|
|
16
|
+
return 1;
|
|
17
|
+
// w:cr is treated as zero-length (consistent with visibleLengthForEl which also returns 0).
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Pre-split revised-tree runs that contain atoms with mixed correlation statuses.
|
|
22
|
+
*
|
|
23
|
+
* Without this, `handleInserted` wraps the entire run with `<w:ins>`, destroying
|
|
24
|
+
* Equal content in the same run. After splitting, each fragment is a separate
|
|
25
|
+
* `<w:r>` and existing per-status handlers work without modification.
|
|
26
|
+
*
|
|
27
|
+
* Safety: wrapped in try/catch per run group. If any DOM operation fails, the
|
|
28
|
+
* run is skipped and the existing fallback-to-rebuild architecture handles it.
|
|
29
|
+
*/
|
|
30
|
+
export function preSplitMixedStatusRuns(mergedAtoms) {
|
|
31
|
+
// Group atoms by their sourceRunElement (revised-tree runs only).
|
|
32
|
+
const runGroups = new Map();
|
|
33
|
+
for (const atom of mergedAtoms) {
|
|
34
|
+
if (!atom.sourceRunElement)
|
|
35
|
+
continue;
|
|
36
|
+
// Skip original-tree atoms — Deleted/MovedSource runs are cloned, not wrapped.
|
|
37
|
+
if (atom.correlationStatus === CorrelationStatus.Deleted ||
|
|
38
|
+
atom.correlationStatus === CorrelationStatus.MovedSource)
|
|
39
|
+
continue;
|
|
40
|
+
// Skip collapsed field atoms (multi-run field sequences).
|
|
41
|
+
if (atom.collapsedFieldAtoms && atom.collapsedFieldAtoms.length > 0)
|
|
42
|
+
continue;
|
|
43
|
+
// Skip field character elements — semantically fragile.
|
|
44
|
+
if (FIELD_CHAR_TAG_NAMES.has(atom.contentElement.tagName))
|
|
45
|
+
continue;
|
|
46
|
+
const group = runGroups.get(atom.sourceRunElement);
|
|
47
|
+
if (group) {
|
|
48
|
+
group.push(atom);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
runGroups.set(atom.sourceRunElement, [atom]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (const [run, atoms] of runGroups) {
|
|
55
|
+
// Early check: skip single-status runs before any DOM work.
|
|
56
|
+
const statuses = new Set(atoms.map((a) => a.correlationStatus));
|
|
57
|
+
if (statuses.size <= 1)
|
|
58
|
+
continue;
|
|
59
|
+
// Guard: skip runs already detached from the tree.
|
|
60
|
+
if (!run.parentNode)
|
|
61
|
+
continue;
|
|
62
|
+
try {
|
|
63
|
+
// Compute the run's actual visible length via DOM traversal.
|
|
64
|
+
const contentEls = getDirectContentElements(run);
|
|
65
|
+
let runVisibleLength = 0;
|
|
66
|
+
for (const cel of contentEls) {
|
|
67
|
+
runVisibleLength += visibleLengthForEl(cel);
|
|
68
|
+
}
|
|
69
|
+
// Cross-run safety: if sum of atom lengths exceeds run visible length,
|
|
70
|
+
// this group contains a cross-run merged atom (passes 3/4). Skip it.
|
|
71
|
+
let sumAtomLengths = 0;
|
|
72
|
+
for (const atom of atoms) {
|
|
73
|
+
sumAtomLengths += atomContentVisibleLength(atom.contentElement);
|
|
74
|
+
}
|
|
75
|
+
if (sumAtomLengths > runVisibleLength)
|
|
76
|
+
continue;
|
|
77
|
+
const spans = [];
|
|
78
|
+
let offset = 0;
|
|
79
|
+
for (const atom of atoms) {
|
|
80
|
+
const len = atomContentVisibleLength(atom.contentElement);
|
|
81
|
+
const lastSpan = spans[spans.length - 1];
|
|
82
|
+
if (lastSpan && lastSpan.status === atom.correlationStatus) {
|
|
83
|
+
lastSpan.length += len;
|
|
84
|
+
lastSpan.atoms.push(atom);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
spans.push({
|
|
88
|
+
status: atom.correlationStatus,
|
|
89
|
+
startOffset: offset,
|
|
90
|
+
length: len,
|
|
91
|
+
atoms: [atom],
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
offset += len;
|
|
95
|
+
}
|
|
96
|
+
// If only one span after grouping, no split needed.
|
|
97
|
+
if (spans.length <= 1)
|
|
98
|
+
continue;
|
|
99
|
+
// Collect split points: startOffset of each span after the first.
|
|
100
|
+
const splitPoints = [];
|
|
101
|
+
for (let i = 1; i < spans.length; i++) {
|
|
102
|
+
const pt = spans[i].startOffset;
|
|
103
|
+
// Filter out degenerate split points at boundaries.
|
|
104
|
+
if (pt > 0 && pt < runVisibleLength) {
|
|
105
|
+
splitPoints.push(pt);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (splitPoints.length === 0)
|
|
109
|
+
continue;
|
|
110
|
+
// Split DOM run right-to-left to keep earlier offsets valid.
|
|
111
|
+
const rightFragments = [];
|
|
112
|
+
for (let i = splitPoints.length - 1; i >= 0; i--) {
|
|
113
|
+
const { right } = splitRunAtVisibleOffset(run, splitPoints[i]);
|
|
114
|
+
rightFragments.push(right);
|
|
115
|
+
}
|
|
116
|
+
// Map fragments: [originalRun (leftmost), ...reverse(rightFragments)]
|
|
117
|
+
// After R-to-L splits, rightFragments are in reverse document order.
|
|
118
|
+
const fragments = [run, ...rightFragments.reverse()];
|
|
119
|
+
// Update atom sourceRunElement pointers to the correct fragment.
|
|
120
|
+
// Each span maps to one fragment in order.
|
|
121
|
+
for (let i = 0; i < spans.length; i++) {
|
|
122
|
+
const fragment = fragments[i];
|
|
123
|
+
if (!fragment)
|
|
124
|
+
continue;
|
|
125
|
+
for (const atom of spans[i].atoms) {
|
|
126
|
+
atom.sourceRunElement = fragment;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (_err) {
|
|
131
|
+
// DOM operation failed — skip this run. The existing fallback-to-rebuild
|
|
132
|
+
// architecture will handle it if the overall safety check fails.
|
|
133
|
+
warn('preSplitMixedStatusRuns', `Skipping run split due to error: ${_err}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Pre-split revised-tree runs where word-split Equal atoms from the same run
|
|
139
|
+
* are interleaved with Deleted/MovedSource atoms in the merged atom list.
|
|
140
|
+
*
|
|
141
|
+
* `preSplitMixedStatusRuns` handles the case where a single run contains atoms
|
|
142
|
+
* with DIFFERENT statuses (e.g., some Equal and some Inserted). But it cannot
|
|
143
|
+
* handle the case where ALL atoms from a run are Equal yet Deleted atoms (from
|
|
144
|
+
* the original tree) are interspersed between them in the merged list.
|
|
145
|
+
*
|
|
146
|
+
* Without this split, `handleEqual` sees all Equal atoms pointing to the same
|
|
147
|
+
* run and skips position advancement (the `lastRevisedRunAnchor` optimization).
|
|
148
|
+
* Subsequent `handleDeleted` calls then insert deleted content at the wrong
|
|
149
|
+
* position because the cursor never advanced past the shared run.
|
|
150
|
+
*
|
|
151
|
+
* This function detects interleaved sequences and splits the DOM run so each
|
|
152
|
+
* contiguous group of Equal atoms gets its own run fragment. The handlers then
|
|
153
|
+
* advance the cursor correctly across fragments.
|
|
154
|
+
*/
|
|
155
|
+
export function preSplitInterleavedWordRuns(mergedAtoms) {
|
|
156
|
+
const runToGroups = new Map();
|
|
157
|
+
// Track cumulative offset per run (sums visible lengths of atoms seen so far)
|
|
158
|
+
const runToOffset = new Map();
|
|
159
|
+
let lastRevisedRun = null;
|
|
160
|
+
for (const atom of mergedAtoms) {
|
|
161
|
+
// Skip atoms from the original tree (Deleted/MovedSource have runs in the
|
|
162
|
+
// original tree, not the revised tree).
|
|
163
|
+
if (atom.correlationStatus === CorrelationStatus.Deleted ||
|
|
164
|
+
atom.correlationStatus === CorrelationStatus.MovedSource) {
|
|
165
|
+
// A Deleted/MovedSource atom between Equal atoms from the same run
|
|
166
|
+
// creates an interleaving gap. Mark this by clearing lastRevisedRun
|
|
167
|
+
// so the next Equal atom from the same run starts a new group.
|
|
168
|
+
lastRevisedRun = null;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const run = atom.sourceRunElement;
|
|
172
|
+
if (!run)
|
|
173
|
+
continue;
|
|
174
|
+
// Skip collapsed field atoms — multi-run field sequences.
|
|
175
|
+
if (atom.collapsedFieldAtoms && atom.collapsedFieldAtoms.length > 0)
|
|
176
|
+
continue;
|
|
177
|
+
// Skip field character elements — semantically fragile.
|
|
178
|
+
if (FIELD_CHAR_TAG_NAMES.has(atom.contentElement.tagName))
|
|
179
|
+
continue;
|
|
180
|
+
const atomLen = atomContentVisibleLength(atom.contentElement);
|
|
181
|
+
const currentOffset = runToOffset.get(run) ?? 0;
|
|
182
|
+
runToOffset.set(run, currentOffset + atomLen);
|
|
183
|
+
const groups = runToGroups.get(run);
|
|
184
|
+
if (!groups) {
|
|
185
|
+
// First time seeing this run — create initial group.
|
|
186
|
+
runToGroups.set(run, [{
|
|
187
|
+
startOffset: currentOffset,
|
|
188
|
+
length: atomLen,
|
|
189
|
+
atoms: [atom],
|
|
190
|
+
}]);
|
|
191
|
+
lastRevisedRun = run;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (lastRevisedRun === run) {
|
|
195
|
+
// Contiguous with the previous atom from the same run — extend group.
|
|
196
|
+
const lastGroup = groups[groups.length - 1];
|
|
197
|
+
lastGroup.length += atomLen;
|
|
198
|
+
lastGroup.atoms.push(atom);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Gap detected (a Deleted/MovedSource atom intervened). Start new group.
|
|
202
|
+
groups.push({
|
|
203
|
+
startOffset: currentOffset,
|
|
204
|
+
length: atomLen,
|
|
205
|
+
atoms: [atom],
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
lastRevisedRun = run;
|
|
209
|
+
}
|
|
210
|
+
// Now split runs that have more than one group.
|
|
211
|
+
for (const [run, groups] of runToGroups) {
|
|
212
|
+
if (groups.length <= 1)
|
|
213
|
+
continue;
|
|
214
|
+
// Guard: skip runs already detached from the tree.
|
|
215
|
+
if (!run.parentNode)
|
|
216
|
+
continue;
|
|
217
|
+
try {
|
|
218
|
+
// Compute actual visible length of the DOM run.
|
|
219
|
+
const contentEls = getDirectContentElements(run);
|
|
220
|
+
let runVisibleLength = 0;
|
|
221
|
+
for (const cel of contentEls) {
|
|
222
|
+
runVisibleLength += visibleLengthForEl(cel);
|
|
223
|
+
}
|
|
224
|
+
// Safety: if the sum of atom lengths exceeds run visible length,
|
|
225
|
+
// something is off (cross-run atoms, etc.). Skip.
|
|
226
|
+
let sumAtomLengths = 0;
|
|
227
|
+
for (const group of groups) {
|
|
228
|
+
sumAtomLengths += group.length;
|
|
229
|
+
}
|
|
230
|
+
if (sumAtomLengths > runVisibleLength)
|
|
231
|
+
continue;
|
|
232
|
+
// Collect split points: the startOffset of each group after the first.
|
|
233
|
+
const splitPoints = [];
|
|
234
|
+
for (let i = 1; i < groups.length; i++) {
|
|
235
|
+
const pt = groups[i].startOffset;
|
|
236
|
+
if (pt > 0 && pt < runVisibleLength) {
|
|
237
|
+
splitPoints.push(pt);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (splitPoints.length === 0)
|
|
241
|
+
continue;
|
|
242
|
+
// Split DOM run right-to-left to keep earlier offsets valid.
|
|
243
|
+
const rightFragments = [];
|
|
244
|
+
for (let i = splitPoints.length - 1; i >= 0; i--) {
|
|
245
|
+
const { right } = splitRunAtVisibleOffset(run, splitPoints[i]);
|
|
246
|
+
rightFragments.push(right);
|
|
247
|
+
}
|
|
248
|
+
// Map fragments: [originalRun (leftmost), ...reverse(rightFragments)]
|
|
249
|
+
const fragments = [run, ...rightFragments.reverse()];
|
|
250
|
+
// Update atom sourceRunElement pointers to the correct fragment.
|
|
251
|
+
for (let i = 0; i < groups.length; i++) {
|
|
252
|
+
const fragment = fragments[i];
|
|
253
|
+
if (!fragment)
|
|
254
|
+
continue;
|
|
255
|
+
for (const atom of groups[i].atoms) {
|
|
256
|
+
atom.sourceRunElement = fragment;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (_err) {
|
|
261
|
+
warn('preSplitInterleavedWordRuns', `Skipping run split due to error: ${_err}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=inPlaceModifier-presplit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inPlaceModifier-presplit.js","sourceRoot":"","sources":["../../../src/baselines/atomizer/inPlaceModifier-presplit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-Place AST Modifier
|
|
3
|
+
*
|
|
4
|
+
* Modifies the revised document's AST in-place to add track changes markup.
|
|
5
|
+
* This replaces the reconstruction-based approach with direct tree manipulation.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComparisonUnitAtom } from '../../core-types.js';
|
|
8
|
+
export declare const SYNTHETIC_DOC: Document;
|
|
9
|
+
export declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
10
|
+
/**
|
|
11
|
+
* Create a namespaced OOXML element with optional attributes.
|
|
12
|
+
* Uses SYNTHETIC_DOC so elements can be adopted by any document tree.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createEl(tag: string, attrs?: Record<string, string>): Element;
|
|
15
|
+
export declare function findAncestorByTag(atom: ComparisonUnitAtom, tagName: string): Element | undefined;
|
|
16
|
+
export declare function attachSourceElementPointers(atoms: ComparisonUnitAtom[]): void;
|
|
17
|
+
export interface RevisionIdState {
|
|
18
|
+
nextId: number;
|
|
19
|
+
moveRangeIds: Map<string, {
|
|
20
|
+
sourceRangeId: number;
|
|
21
|
+
destRangeId: number;
|
|
22
|
+
}>;
|
|
23
|
+
/** Track which run elements have already been wrapped */
|
|
24
|
+
wrappedRuns: Set<Element>;
|
|
25
|
+
/**
|
|
26
|
+
* Source bookmark markers cloned into inserted deleted/moveFrom content.
|
|
27
|
+
* Prevents duplicate marker emission when a single source run is split into
|
|
28
|
+
* multiple atoms (word-level atomization).
|
|
29
|
+
*/
|
|
30
|
+
emittedSourceBookmarkMarkers: Set<Element>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create initial revision ID state.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createRevisionIdState(): RevisionIdState;
|
|
36
|
+
/**
|
|
37
|
+
* Allocate a new revision ID.
|
|
38
|
+
*/
|
|
39
|
+
export declare function allocateRevisionId(state: RevisionIdState): number;
|
|
40
|
+
/**
|
|
41
|
+
* Get or allocate move range IDs for a move name.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getMoveRangeIds(state: RevisionIdState, moveName: string): {
|
|
44
|
+
sourceRangeId: number;
|
|
45
|
+
destRangeId: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Format date for OOXML (ISO 8601 without milliseconds).
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatDate(date: Date): string;
|
|
51
|
+
/**
|
|
52
|
+
* Convert w:t elements to w:delText within an element tree.
|
|
53
|
+
*
|
|
54
|
+
* @param element - The element to process
|
|
55
|
+
*/
|
|
56
|
+
export declare function convertToDelText(element: Element): void;
|
|
57
|
+
export declare function parentElement(node: Element): Element | null;
|
|
58
|
+
export declare function findTreeRoot(node: Element): Element;
|
|
59
|
+
export declare function findAncestor(node: Element | undefined, tagName: string): Element | undefined;
|
|
60
|
+
export declare function hasAncestorTag(node: Element | undefined, tagNames: ReadonlySet<string>): boolean;
|
|
61
|
+
export declare function paragraphHasParaInsMarker(paragraph: Element | undefined): boolean;
|
|
62
|
+
//# sourceMappingURL=inPlaceModifier-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inPlaceModifier-shared.d.ts","sourceRoot":"","sources":["../../../src/baselines/atomizer/inPlaceModifier-shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAI9D,eAAO,MAAM,aAAa,UAA6F,CAAC;AACxH,eAAO,MAAM,IAAI,iEAAiE,CAAC;AAEnF;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAI7E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMhG;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAK7E;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,yDAAyD;IACzD,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1B;;;;OAIG;IACH,4BAA4B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAOvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,MAAM,GACf;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAUhD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBvD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAG3D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAQnD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAO5F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAShG;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CASjF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-Place AST Modifier
|
|
3
|
+
*
|
|
4
|
+
* Modifies the revised document's AST in-place to add track changes markup.
|
|
5
|
+
* This replaces the reconstruction-based approach with direct tree manipulation.
|
|
6
|
+
*/
|
|
7
|
+
import { childElements, findChildByTagName } from '../../primitives/index.js';
|
|
8
|
+
import { parseXml } from '../../primitives/xml.js';
|
|
9
|
+
export const SYNTHETIC_DOC = parseXml('<root xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>');
|
|
10
|
+
export const W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
11
|
+
/**
|
|
12
|
+
* Create a namespaced OOXML element with optional attributes.
|
|
13
|
+
* Uses SYNTHETIC_DOC so elements can be adopted by any document tree.
|
|
14
|
+
*/
|
|
15
|
+
export function createEl(tag, attrs) {
|
|
16
|
+
const el = SYNTHETIC_DOC.createElementNS(W_NS, tag);
|
|
17
|
+
if (attrs)
|
|
18
|
+
for (const [k, v] of Object.entries(attrs))
|
|
19
|
+
el.setAttribute(k, v);
|
|
20
|
+
return el;
|
|
21
|
+
}
|
|
22
|
+
export function findAncestorByTag(atom, tagName) {
|
|
23
|
+
for (let i = atom.ancestorElements.length - 1; i >= 0; i--) {
|
|
24
|
+
const el = atom.ancestorElements[i];
|
|
25
|
+
if (el.tagName === tagName)
|
|
26
|
+
return el;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
export function attachSourceElementPointers(atoms) {
|
|
31
|
+
for (const atom of atoms) {
|
|
32
|
+
atom.sourceRunElement = findAncestorByTag(atom, 'w:r');
|
|
33
|
+
atom.sourceParagraphElement = findAncestorByTag(atom, 'w:p');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create initial revision ID state.
|
|
38
|
+
*/
|
|
39
|
+
export function createRevisionIdState() {
|
|
40
|
+
return {
|
|
41
|
+
nextId: 1,
|
|
42
|
+
moveRangeIds: new Map(),
|
|
43
|
+
wrappedRuns: new Set(),
|
|
44
|
+
emittedSourceBookmarkMarkers: new Set(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Allocate a new revision ID.
|
|
49
|
+
*/
|
|
50
|
+
export function allocateRevisionId(state) {
|
|
51
|
+
return state.nextId++;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get or allocate move range IDs for a move name.
|
|
55
|
+
*/
|
|
56
|
+
export function getMoveRangeIds(state, moveName) {
|
|
57
|
+
let ids = state.moveRangeIds.get(moveName);
|
|
58
|
+
if (!ids) {
|
|
59
|
+
ids = {
|
|
60
|
+
sourceRangeId: allocateRevisionId(state),
|
|
61
|
+
destRangeId: allocateRevisionId(state),
|
|
62
|
+
};
|
|
63
|
+
state.moveRangeIds.set(moveName, ids);
|
|
64
|
+
}
|
|
65
|
+
return ids;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Format date for OOXML (ISO 8601 without milliseconds).
|
|
69
|
+
*/
|
|
70
|
+
export function formatDate(date) {
|
|
71
|
+
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Convert w:t elements to w:delText within an element tree.
|
|
75
|
+
*
|
|
76
|
+
* @param element - The element to process
|
|
77
|
+
*/
|
|
78
|
+
export function convertToDelText(element) {
|
|
79
|
+
if (element.tagName === 'w:t' || element.tagName === 'w:instrText') {
|
|
80
|
+
const newTag = element.tagName === 'w:t' ? 'w:delText' : 'w:delInstrText';
|
|
81
|
+
const newEl = createEl(newTag);
|
|
82
|
+
// Copy text content
|
|
83
|
+
while (element.firstChild)
|
|
84
|
+
newEl.appendChild(element.firstChild);
|
|
85
|
+
// Copy attributes
|
|
86
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
87
|
+
const attr = element.attributes[i];
|
|
88
|
+
newEl.setAttribute(attr.name, attr.value);
|
|
89
|
+
}
|
|
90
|
+
element.parentNode?.replaceChild(newEl, element);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
for (const child of childElements(element)) {
|
|
94
|
+
convertToDelText(child);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export function parentElement(node) {
|
|
98
|
+
const p = node.parentNode;
|
|
99
|
+
return p && p.nodeType === 1 ? p : null;
|
|
100
|
+
}
|
|
101
|
+
export function findTreeRoot(node) {
|
|
102
|
+
let current = node;
|
|
103
|
+
let parent = parentElement(current);
|
|
104
|
+
while (parent) {
|
|
105
|
+
current = parent;
|
|
106
|
+
parent = parentElement(current);
|
|
107
|
+
}
|
|
108
|
+
return current;
|
|
109
|
+
}
|
|
110
|
+
export function findAncestor(node, tagName) {
|
|
111
|
+
let current = node ?? null;
|
|
112
|
+
while (current) {
|
|
113
|
+
if (current.tagName === tagName)
|
|
114
|
+
return current;
|
|
115
|
+
current = parentElement(current);
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
export function hasAncestorTag(node, tagNames) {
|
|
120
|
+
let current = node ? parentElement(node) : null;
|
|
121
|
+
while (current) {
|
|
122
|
+
if (tagNames.has(current.tagName)) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
current = parentElement(current);
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
export function paragraphHasParaInsMarker(paragraph) {
|
|
130
|
+
if (!paragraph || paragraph.tagName !== 'w:p') {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const pPr = findChildByTagName(paragraph, 'w:pPr');
|
|
134
|
+
if (!pPr) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return Array.from(pPr.getElementsByTagName('w:ins')).length > 0;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=inPlaceModifier-shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inPlaceModifier-shared.js","sourceRoot":"","sources":["../../../src/baselines/atomizer/inPlaceModifier-shared.ts"],"names":[],"mappings":"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"}
|