docxmlater 10.2.2 → 10.2.3
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/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +44 -0
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +6 -4
- package/dist/elements/Field.js.map +1 -1
- package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
- package/dist/utils/InMemoryRevisionAcceptor.js +24 -4
- package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
- package/package.json +1 -1
- package/src/core/DocumentParser.ts +50 -1
- package/src/elements/Field.ts +10 -7
- package/src/utils/InMemoryRevisionAcceptor.ts +31 -4
package/package.json
CHANGED
|
@@ -2689,6 +2689,7 @@ export class DocumentParser {
|
|
|
2689
2689
|
let fieldRuns: Run[] = [];
|
|
2690
2690
|
let fieldRevisions: Revision[] = []; // Track revisions inside field result section
|
|
2691
2691
|
let instructionRevisions: Revision[] = []; // Track revisions in instruction area
|
|
2692
|
+
let orderedResultItems: Array<Run | Revision> = []; // Track interleaved order of result runs + revisions
|
|
2692
2693
|
let fieldState: 'begin' | 'instruction' | 'separate' | 'result' | 'end' | null = null;
|
|
2693
2694
|
let nestingDepth = 0;
|
|
2694
2695
|
let hasNestedFields = false;
|
|
@@ -2749,6 +2750,7 @@ export class DocumentParser {
|
|
|
2749
2750
|
fieldRuns = [];
|
|
2750
2751
|
instructionRevisions = [];
|
|
2751
2752
|
fieldRevisions = [];
|
|
2753
|
+
orderedResultItems = [];
|
|
2752
2754
|
fieldState = null;
|
|
2753
2755
|
hasNestedFields = false;
|
|
2754
2756
|
fieldStartIndex = -1;
|
|
@@ -2801,6 +2803,7 @@ export class DocumentParser {
|
|
|
2801
2803
|
fieldRuns = [];
|
|
2802
2804
|
instructionRevisions = [];
|
|
2803
2805
|
fieldRevisions = [];
|
|
2806
|
+
orderedResultItems = [];
|
|
2804
2807
|
fieldState = null;
|
|
2805
2808
|
break;
|
|
2806
2809
|
}
|
|
@@ -2840,6 +2843,39 @@ export class DocumentParser {
|
|
|
2840
2843
|
if (fieldRevisions.length > 0) {
|
|
2841
2844
|
const complexField = this.createComplexFieldFromRuns(fieldRuns);
|
|
2842
2845
|
if (complexField) {
|
|
2846
|
+
// Build ordered resultContent for correct round-trip serialization
|
|
2847
|
+
if (orderedResultItems.length > 0) {
|
|
2848
|
+
const orderedContent: XMLElement[] = [];
|
|
2849
|
+
for (const resultItem of orderedResultItems) {
|
|
2850
|
+
if (resultItem instanceof Run) {
|
|
2851
|
+
orderedContent.push(resultItem.toXML());
|
|
2852
|
+
} else if (resultItem instanceof Revision) {
|
|
2853
|
+
const xml = resultItem.toXML();
|
|
2854
|
+
if (xml) orderedContent.push(xml);
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
// Compute accepted text (non-revision runs + insertion text)
|
|
2858
|
+
let acceptedText = '';
|
|
2859
|
+
for (const resultItem of orderedResultItems) {
|
|
2860
|
+
if (resultItem instanceof Run) {
|
|
2861
|
+
acceptedText += resultItem.getText() || '';
|
|
2862
|
+
} else if (
|
|
2863
|
+
resultItem instanceof Revision &&
|
|
2864
|
+
resultItem.getType() === 'insert'
|
|
2865
|
+
) {
|
|
2866
|
+
for (const child of resultItem.getRuns()) {
|
|
2867
|
+
acceptedText += child.getText() || '';
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
// Set accepted text as the result (for getResult() API)
|
|
2872
|
+
complexField.setResult(acceptedText || complexField.getResult() || '');
|
|
2873
|
+
// Add ordered content for serialization (overrides the text-based path)
|
|
2874
|
+
for (const xmlEl of orderedContent) {
|
|
2875
|
+
complexField.addResultContent(xmlEl);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
// Attach revisions for tracking/acceptance
|
|
2843
2879
|
for (const rev of fieldRevisions) {
|
|
2844
2880
|
rev.setFieldContext({
|
|
2845
2881
|
field: complexField,
|
|
@@ -2858,6 +2894,7 @@ export class DocumentParser {
|
|
|
2858
2894
|
fieldRuns = [];
|
|
2859
2895
|
instructionRevisions = [];
|
|
2860
2896
|
fieldRevisions = [];
|
|
2897
|
+
orderedResultItems = [];
|
|
2861
2898
|
fieldState = null;
|
|
2862
2899
|
break;
|
|
2863
2900
|
}
|
|
@@ -2905,6 +2942,7 @@ export class DocumentParser {
|
|
|
2905
2942
|
fieldRuns = [];
|
|
2906
2943
|
instructionRevisions = [];
|
|
2907
2944
|
fieldRevisions = [];
|
|
2945
|
+
orderedResultItems = [];
|
|
2908
2946
|
fieldState = null;
|
|
2909
2947
|
break;
|
|
2910
2948
|
}
|
|
@@ -2924,6 +2962,7 @@ export class DocumentParser {
|
|
|
2924
2962
|
fieldRuns = [];
|
|
2925
2963
|
instructionRevisions = [];
|
|
2926
2964
|
fieldRevisions = [];
|
|
2965
|
+
orderedResultItems = [];
|
|
2927
2966
|
fieldState = null;
|
|
2928
2967
|
break;
|
|
2929
2968
|
}
|
|
@@ -2958,6 +2997,7 @@ export class DocumentParser {
|
|
|
2958
2997
|
fieldRuns = [];
|
|
2959
2998
|
instructionRevisions = [];
|
|
2960
2999
|
fieldRevisions = [];
|
|
3000
|
+
orderedResultItems = [];
|
|
2961
3001
|
fieldState = null;
|
|
2962
3002
|
}
|
|
2963
3003
|
break;
|
|
@@ -2971,11 +3011,16 @@ export class DocumentParser {
|
|
|
2971
3011
|
} else {
|
|
2972
3012
|
// Regular run - check if we're inside a field result section
|
|
2973
3013
|
if (nestingDepth > 0) {
|
|
2974
|
-
// Inside a
|
|
3014
|
+
// Inside a field - collect all runs to preserve raw structure
|
|
2975
3015
|
fieldRuns.push(item);
|
|
3016
|
+
// Track result runs for interleaved ordering (only outer field level)
|
|
3017
|
+
if (nestingDepth === 1 && (fieldState === 'separate' || fieldState === 'result')) {
|
|
3018
|
+
orderedResultItems.push(item);
|
|
3019
|
+
}
|
|
2976
3020
|
} else if (fieldState === 'separate' || fieldState === 'result') {
|
|
2977
3021
|
// This run is part of the field result - collect it
|
|
2978
3022
|
fieldRuns.push(item);
|
|
3023
|
+
orderedResultItems.push(item);
|
|
2979
3024
|
fieldState = 'result';
|
|
2980
3025
|
} else if (fieldState === 'begin' || fieldState === 'instruction') {
|
|
2981
3026
|
// We're in the middle of parsing field instruction
|
|
@@ -2994,6 +3039,7 @@ export class DocumentParser {
|
|
|
2994
3039
|
fieldRuns = [];
|
|
2995
3040
|
instructionRevisions = [];
|
|
2996
3041
|
fieldRevisions = [];
|
|
3042
|
+
orderedResultItems = [];
|
|
2997
3043
|
fieldState = null;
|
|
2998
3044
|
groupedContent.push(item);
|
|
2999
3045
|
} else {
|
|
@@ -3010,6 +3056,7 @@ export class DocumentParser {
|
|
|
3010
3056
|
// Set preliminary field context (field reference will be set when ComplexField is created)
|
|
3011
3057
|
item.setFieldContext({ position: 'result' });
|
|
3012
3058
|
fieldRevisions.push(item);
|
|
3059
|
+
orderedResultItems.push(item);
|
|
3013
3060
|
fieldState = 'result';
|
|
3014
3061
|
defaultLogger.debug(
|
|
3015
3062
|
`Found revision inside complex field result: type=${item.getType()}, id=${item.getId()}`
|
|
@@ -3038,6 +3085,7 @@ export class DocumentParser {
|
|
|
3038
3085
|
fieldRuns = [];
|
|
3039
3086
|
instructionRevisions = [];
|
|
3040
3087
|
fieldRevisions = [];
|
|
3088
|
+
orderedResultItems = [];
|
|
3041
3089
|
fieldState = null;
|
|
3042
3090
|
groupedContent.push(item);
|
|
3043
3091
|
} else {
|
|
@@ -3061,6 +3109,7 @@ export class DocumentParser {
|
|
|
3061
3109
|
fieldRuns = [];
|
|
3062
3110
|
instructionRevisions = [];
|
|
3063
3111
|
fieldRevisions = [];
|
|
3112
|
+
orderedResultItems = [];
|
|
3064
3113
|
fieldState = null;
|
|
3065
3114
|
}
|
|
3066
3115
|
groupedContent.push(item);
|
package/src/elements/Field.ts
CHANGED
|
@@ -970,13 +970,16 @@ export class ComplexField {
|
|
|
970
970
|
});
|
|
971
971
|
}
|
|
972
972
|
|
|
973
|
-
// 4a. Result revisions
|
|
974
|
-
//
|
|
975
|
-
//
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
973
|
+
// 4a. Result revisions — only when NOT using resultContent
|
|
974
|
+
// When resultContent is populated (e.g., by DocumentParser with interleaved revision XML),
|
|
975
|
+
// it already includes revision elements in the correct interleaved position.
|
|
976
|
+
// Emitting them again here would cause duplication.
|
|
977
|
+
if (this.resultContent.length === 0) {
|
|
978
|
+
for (const revision of this.resultRevisions) {
|
|
979
|
+
const revisionXml = revision.toXML();
|
|
980
|
+
if (revisionXml) {
|
|
981
|
+
runs.push(revisionXml);
|
|
982
|
+
}
|
|
980
983
|
}
|
|
981
984
|
}
|
|
982
985
|
|
|
@@ -547,15 +547,42 @@ function acceptRevisionsInParagraph(
|
|
|
547
547
|
newContent.push(item);
|
|
548
548
|
} else if (item instanceof ComplexField && item.hasResultRevisions()) {
|
|
549
549
|
// Accept revisions nested inside ComplexField result sections
|
|
550
|
+
// Merge insertion/moveTo text into the result before clearing
|
|
550
551
|
const fieldRevisions = item.getResultRevisions();
|
|
552
|
+
let mergedResult = item.getResult() || '';
|
|
553
|
+
const revisionsToKeep: Revision[] = [];
|
|
554
|
+
|
|
551
555
|
for (const rev of fieldRevisions) {
|
|
552
556
|
const revType = rev.getType();
|
|
553
|
-
if (revType === 'insert' && options.acceptInsertions)
|
|
554
|
-
|
|
555
|
-
|
|
557
|
+
if (revType === 'insert' && options.acceptInsertions) {
|
|
558
|
+
// Merge insertion text into result
|
|
559
|
+
for (const child of rev.getRuns()) {
|
|
560
|
+
mergedResult += child.getText() || '';
|
|
561
|
+
}
|
|
562
|
+
result.insertionsAccepted++;
|
|
563
|
+
} else if (revType === 'delete' && options.acceptDeletions) {
|
|
564
|
+
// Deleted text was never in result — just count it
|
|
565
|
+
result.deletionsAccepted++;
|
|
566
|
+
} else if (revType === 'moveTo' && options.acceptMoves) {
|
|
567
|
+
// Merge moveTo text into result
|
|
568
|
+
for (const child of rev.getRuns()) {
|
|
569
|
+
mergedResult += child.getText() || '';
|
|
570
|
+
}
|
|
571
|
+
result.movesAccepted++;
|
|
572
|
+
} else if (revType === 'moveFrom' && options.acceptMoves) {
|
|
556
573
|
result.movesAccepted++;
|
|
574
|
+
} else {
|
|
575
|
+
// Revision type not being accepted — keep it
|
|
576
|
+
revisionsToKeep.push(rev);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// setResult() clears both resultRevisions and resultContent
|
|
581
|
+
item.setResult(mergedResult);
|
|
582
|
+
// Restore any unaccepted revisions
|
|
583
|
+
if (revisionsToKeep.length > 0) {
|
|
584
|
+
item.setResultRevisions(revisionsToKeep);
|
|
557
585
|
}
|
|
558
|
-
item.setResultRevisions([]); // Clear after acceptance
|
|
559
586
|
newContent.push(item);
|
|
560
587
|
} else {
|
|
561
588
|
// Non-revision content - keep as-is
|