@adeu/core 1.18.5 → 1.19.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/index.cjs +271 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +271 -76
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine.ts +364 -91
- package/src/repro.indexed-edit-insertion-loss.test.ts +137 -0
- package/src/repro.report.test.ts +1 -0
- package/src/repro_surgical_word_diff.test.ts +26 -0
package/dist/index.cjs
CHANGED
|
@@ -3081,6 +3081,76 @@ var RedlineEngine = class {
|
|
|
3081
3081
|
}
|
|
3082
3082
|
return null;
|
|
3083
3083
|
}
|
|
3084
|
+
_word_diff_sub_edits(target_str, new_str, base_offset, parent_comment = null, is_table = false, active_mapper = null) {
|
|
3085
|
+
let raw_sub_edits = [];
|
|
3086
|
+
try {
|
|
3087
|
+
raw_sub_edits = generate_edits_from_text(target_str, new_str);
|
|
3088
|
+
console.log("_word_diff_sub_edits RAW_SUB_EDITS:", JSON.stringify(raw_sub_edits, null, 2));
|
|
3089
|
+
} catch (e) {
|
|
3090
|
+
console.warn("generate_edits_from_text failed, falling back to wholesale edit", e);
|
|
3091
|
+
raw_sub_edits = [];
|
|
3092
|
+
}
|
|
3093
|
+
if (!raw_sub_edits || raw_sub_edits.length === 0) {
|
|
3094
|
+
const fallback_edit = {
|
|
3095
|
+
type: "modify",
|
|
3096
|
+
target_text: target_str,
|
|
3097
|
+
new_text: new_str,
|
|
3098
|
+
comment: parent_comment
|
|
3099
|
+
};
|
|
3100
|
+
fallback_edit._resolved_start_idx = base_offset;
|
|
3101
|
+
fallback_edit._match_start_index = base_offset;
|
|
3102
|
+
fallback_edit._active_mapper_ref = active_mapper;
|
|
3103
|
+
if (is_table) {
|
|
3104
|
+
fallback_edit._is_table_edit = true;
|
|
3105
|
+
}
|
|
3106
|
+
if (target_str === new_str) {
|
|
3107
|
+
fallback_edit._internal_op = "COMMENT_ONLY";
|
|
3108
|
+
} else if (!target_str && new_str) {
|
|
3109
|
+
fallback_edit._internal_op = "INSERTION";
|
|
3110
|
+
} else if (target_str && !new_str) {
|
|
3111
|
+
fallback_edit._internal_op = "DELETION";
|
|
3112
|
+
} else if (target_str && new_str) {
|
|
3113
|
+
fallback_edit._internal_op = "MODIFICATION";
|
|
3114
|
+
} else {
|
|
3115
|
+
fallback_edit._internal_op = "COMMENT_ONLY";
|
|
3116
|
+
}
|
|
3117
|
+
return [fallback_edit];
|
|
3118
|
+
}
|
|
3119
|
+
const sub_edits = [];
|
|
3120
|
+
let comment_assigned = false;
|
|
3121
|
+
for (const raw_edit of raw_sub_edits) {
|
|
3122
|
+
const sub_start = base_offset + (raw_edit._match_start_index || 0);
|
|
3123
|
+
const should_attach_comment = parent_comment !== null && !comment_assigned;
|
|
3124
|
+
if (should_attach_comment) {
|
|
3125
|
+
comment_assigned = true;
|
|
3126
|
+
}
|
|
3127
|
+
const sub_edit = {
|
|
3128
|
+
type: "modify",
|
|
3129
|
+
target_text: raw_edit.target_text,
|
|
3130
|
+
new_text: raw_edit.new_text,
|
|
3131
|
+
comment: should_attach_comment ? parent_comment : null
|
|
3132
|
+
};
|
|
3133
|
+
sub_edit._resolved_start_idx = sub_start;
|
|
3134
|
+
sub_edit._match_start_index = sub_start;
|
|
3135
|
+
sub_edit._active_mapper_ref = active_mapper;
|
|
3136
|
+
if (is_table) {
|
|
3137
|
+
sub_edit._is_table_edit = true;
|
|
3138
|
+
}
|
|
3139
|
+
const t_val = raw_edit.target_text;
|
|
3140
|
+
const n_val = raw_edit.new_text;
|
|
3141
|
+
if (!t_val && n_val) {
|
|
3142
|
+
sub_edit._internal_op = "INSERTION";
|
|
3143
|
+
} else if (t_val && !n_val) {
|
|
3144
|
+
sub_edit._internal_op = "DELETION";
|
|
3145
|
+
} else if (t_val && n_val) {
|
|
3146
|
+
sub_edit._internal_op = "MODIFICATION";
|
|
3147
|
+
} else {
|
|
3148
|
+
sub_edit._internal_op = "COMMENT_ONLY";
|
|
3149
|
+
}
|
|
3150
|
+
sub_edits.push(sub_edit);
|
|
3151
|
+
}
|
|
3152
|
+
return sub_edits;
|
|
3153
|
+
}
|
|
3084
3154
|
/**
|
|
3085
3155
|
* Best-effort "did you mean" hint for a failed target. The common loop trap
|
|
3086
3156
|
* (observed in the field) is an anchored regex like `^\( x \)$` against a
|
|
@@ -4010,6 +4080,8 @@ var RedlineEngine = class {
|
|
|
4010
4080
|
continue;
|
|
4011
4081
|
}
|
|
4012
4082
|
if (!edit.target_text) continue;
|
|
4083
|
+
if (edit._match_start_index !== void 0 && edit._match_start_index !== null || edit._resolved_start_idx !== void 0 && edit._resolved_start_idx !== null)
|
|
4084
|
+
continue;
|
|
4013
4085
|
const is_regex = edit.regex || false;
|
|
4014
4086
|
const match_mode = edit.match_mode || "strict";
|
|
4015
4087
|
let matches = this.mapper.find_all_match_indices(
|
|
@@ -4313,16 +4385,31 @@ var RedlineEngine = class {
|
|
|
4313
4385
|
let applied_edits = 0;
|
|
4314
4386
|
let skipped_edits = 0;
|
|
4315
4387
|
if (edits.length > 0) {
|
|
4388
|
+
const pinned_idx = (e) => {
|
|
4389
|
+
if (e._resolved_start_idx !== void 0 && e._resolved_start_idx !== null)
|
|
4390
|
+
return e._resolved_start_idx;
|
|
4391
|
+
if (e._match_start_index !== void 0 && e._match_start_index !== null)
|
|
4392
|
+
return e._match_start_index;
|
|
4393
|
+
return null;
|
|
4394
|
+
};
|
|
4395
|
+
const ordered_edits = edits.map((edit, i) => ({ edit, i })).sort((a, b) => {
|
|
4396
|
+
const ka = pinned_idx(a.edit);
|
|
4397
|
+
const kb = pinned_idx(b.edit);
|
|
4398
|
+
if (ka === null && kb === null) return a.i - b.i;
|
|
4399
|
+
if (ka === null) return 1;
|
|
4400
|
+
if (kb === null) return -1;
|
|
4401
|
+
return kb - ka || a.i - b.i;
|
|
4402
|
+
});
|
|
4316
4403
|
if (dry_run_mode) {
|
|
4317
|
-
|
|
4318
|
-
|
|
4404
|
+
const reports_by_input = new Array(edits.length);
|
|
4405
|
+
for (const { edit, i } of ordered_edits) {
|
|
4319
4406
|
const single_errors = this.validate_edits([edit], i);
|
|
4320
4407
|
if (single_errors.length > 0) {
|
|
4321
4408
|
skipped_edits++;
|
|
4322
4409
|
const warning = this._check_punctuation_warning(
|
|
4323
4410
|
edit.target_text || ""
|
|
4324
4411
|
);
|
|
4325
|
-
|
|
4412
|
+
reports_by_input[i] = {
|
|
4326
4413
|
status: "failed",
|
|
4327
4414
|
target_text: edit.target_text || "",
|
|
4328
4415
|
new_text: edit.new_text || "",
|
|
@@ -4330,14 +4417,14 @@ var RedlineEngine = class {
|
|
|
4330
4417
|
error: single_errors[0],
|
|
4331
4418
|
critic_markup: null,
|
|
4332
4419
|
clean_text: null
|
|
4333
|
-
}
|
|
4420
|
+
};
|
|
4334
4421
|
continue;
|
|
4335
4422
|
}
|
|
4336
4423
|
const res = this.apply_edits([edit], page_offsets);
|
|
4337
4424
|
if (edit._applied_status) {
|
|
4338
4425
|
applied_edits++;
|
|
4339
4426
|
const previews = this._build_edit_context_previews(edit);
|
|
4340
|
-
|
|
4427
|
+
reports_by_input[i] = {
|
|
4341
4428
|
status: "applied",
|
|
4342
4429
|
target_text: edit.target_text || "",
|
|
4343
4430
|
new_text: edit.new_text || "",
|
|
@@ -4349,7 +4436,7 @@ var RedlineEngine = class {
|
|
|
4349
4436
|
heading_path: edit._heading_path || "",
|
|
4350
4437
|
occurrences_modified: edit._occurrences_modified || 0,
|
|
4351
4438
|
match_mode: edit.match_mode || "strict"
|
|
4352
|
-
}
|
|
4439
|
+
};
|
|
4353
4440
|
this.mapper = new DocumentMapper(this.doc);
|
|
4354
4441
|
this.clean_mapper = null;
|
|
4355
4442
|
} else {
|
|
@@ -4358,7 +4445,7 @@ var RedlineEngine = class {
|
|
|
4358
4445
|
const warning = this._check_punctuation_warning(
|
|
4359
4446
|
edit.target_text || ""
|
|
4360
4447
|
);
|
|
4361
|
-
|
|
4448
|
+
reports_by_input[i] = {
|
|
4362
4449
|
status: "failed",
|
|
4363
4450
|
target_text: edit.target_text || "",
|
|
4364
4451
|
new_text: edit.new_text || "",
|
|
@@ -4366,16 +4453,16 @@ var RedlineEngine = class {
|
|
|
4366
4453
|
error: error_msg,
|
|
4367
4454
|
critic_markup: null,
|
|
4368
4455
|
clean_text: null
|
|
4369
|
-
}
|
|
4456
|
+
};
|
|
4370
4457
|
}
|
|
4371
4458
|
}
|
|
4459
|
+
edits_reports.push(...reports_by_input);
|
|
4372
4460
|
} else {
|
|
4373
4461
|
const snapshot = takeSnapshot(this.doc);
|
|
4374
4462
|
const originalCurrentId = this.current_id;
|
|
4375
4463
|
try {
|
|
4376
4464
|
const sequential_errors = [];
|
|
4377
|
-
for (
|
|
4378
|
-
const edit = edits[i];
|
|
4465
|
+
for (const { edit, i } of ordered_edits) {
|
|
4379
4466
|
const single_errors = this.validate_edits([edit], i);
|
|
4380
4467
|
if (single_errors.length > 0) {
|
|
4381
4468
|
sequential_errors.push(...single_errors);
|
|
@@ -4543,7 +4630,8 @@ var RedlineEngine = class {
|
|
|
4543
4630
|
}
|
|
4544
4631
|
let success = false;
|
|
4545
4632
|
if (edit.type === "modify") {
|
|
4546
|
-
|
|
4633
|
+
const rebuild = edit._split_group_id !== void 0 && edit._split_group_id !== null;
|
|
4634
|
+
success = this._apply_single_edit_indexed(edit, orig_new, rebuild);
|
|
4547
4635
|
} else if (edit.type === "insert_row" || edit.type === "delete_row") {
|
|
4548
4636
|
success = this._apply_table_edit(edit, false);
|
|
4549
4637
|
}
|
|
@@ -4851,15 +4939,87 @@ var RedlineEngine = class {
|
|
|
4851
4939
|
});
|
|
4852
4940
|
continue;
|
|
4853
4941
|
}
|
|
4942
|
+
let overlaps_virtual_pipe = false;
|
|
4943
|
+
if (active_mapper) {
|
|
4944
|
+
overlaps_virtual_pipe = active_mapper.spans.some(
|
|
4945
|
+
(s) => s.text === " | " && (s.run === null || s.run === void 0) && s.start < start_idx + match_len && s.end > start_idx
|
|
4946
|
+
);
|
|
4947
|
+
}
|
|
4948
|
+
if (overlaps_virtual_pipe) {
|
|
4949
|
+
const actual_cells = actual_doc_text.split("|");
|
|
4950
|
+
const new_cells = current_effective_new_text.split("|");
|
|
4951
|
+
if (actual_cells.length === new_cells.length && actual_cells.length > 1) {
|
|
4952
|
+
const sub_edits2 = [];
|
|
4953
|
+
let search_offset = start_idx;
|
|
4954
|
+
let target_comment_idx = 0;
|
|
4955
|
+
for (let idx = 0; idx < actual_cells.length; idx++) {
|
|
4956
|
+
if (actual_cells[idx].trim() !== new_cells[idx].trim()) {
|
|
4957
|
+
target_comment_idx = idx;
|
|
4958
|
+
break;
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
for (let cell_idx = 0; cell_idx < actual_cells.length; cell_idx++) {
|
|
4962
|
+
const a_cell = actual_cells[cell_idx];
|
|
4963
|
+
const n_cell = new_cells[cell_idx];
|
|
4964
|
+
const a_clean = a_cell.trim();
|
|
4965
|
+
const n_clean = n_cell.trim();
|
|
4966
|
+
let actual_start = search_offset;
|
|
4967
|
+
if (a_clean) {
|
|
4968
|
+
actual_start = this.mapper.full_text.indexOf(a_clean, search_offset);
|
|
4969
|
+
if (actual_start === -1 || actual_start > search_offset + 10) {
|
|
4970
|
+
actual_start = search_offset;
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
const should_attach_comment = edit.comment !== null && edit.comment !== void 0 && cell_idx === target_comment_idx;
|
|
4974
|
+
if (a_clean !== n_clean || should_attach_comment) {
|
|
4975
|
+
const cell_sub_edits = this._word_diff_sub_edits(
|
|
4976
|
+
a_clean,
|
|
4977
|
+
n_clean,
|
|
4978
|
+
actual_start,
|
|
4979
|
+
should_attach_comment ? edit.comment : null,
|
|
4980
|
+
true,
|
|
4981
|
+
active_mapper
|
|
4982
|
+
);
|
|
4983
|
+
for (const se of cell_sub_edits) {
|
|
4984
|
+
se._original_target_text = edit.target_text;
|
|
4985
|
+
se._split_group_id = start_idx;
|
|
4986
|
+
sub_edits2.push(se);
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
if (a_clean) {
|
|
4990
|
+
search_offset = actual_start + a_clean.length;
|
|
4991
|
+
}
|
|
4992
|
+
const next_pipe = this.mapper.full_text.indexOf(" | ", search_offset);
|
|
4993
|
+
if (next_pipe !== -1 && next_pipe <= search_offset + 10) {
|
|
4994
|
+
search_offset = next_pipe + 3;
|
|
4995
|
+
} else {
|
|
4996
|
+
search_offset += a_cell.length + 1;
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
for (const sub of sub_edits2) {
|
|
5000
|
+
all_sub_edits.push(sub);
|
|
5001
|
+
}
|
|
5002
|
+
continue;
|
|
5003
|
+
} else {
|
|
5004
|
+
throw new BatchValidationError([
|
|
5005
|
+
`Target text spans ${actual_cells.length} table cells, but replacement provides ${new_cells.length}. To modify text without altering table structure (rows or columns), ensure the replacement contains the exact same number of '|' separators (e.g., replace with 'CellC | ' to empty the second cell).`
|
|
5006
|
+
]);
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
5009
|
+
let has_markdown = false;
|
|
5010
|
+
if (edit.target_text && (edit.target_text.includes("**") || edit.target_text.includes("_"))) {
|
|
5011
|
+
has_markdown = true;
|
|
5012
|
+
}
|
|
5013
|
+
if (current_effective_new_text && (current_effective_new_text.includes("**") || current_effective_new_text.includes("_"))) {
|
|
5014
|
+
has_markdown = true;
|
|
5015
|
+
}
|
|
4854
5016
|
let effective_op = "";
|
|
4855
5017
|
let final_target = "";
|
|
4856
5018
|
let final_new = "";
|
|
4857
5019
|
let effective_start_idx = start_idx;
|
|
4858
5020
|
if (current_effective_new_text.startsWith(actual_doc_text)) {
|
|
4859
5021
|
effective_op = "INSERTION";
|
|
4860
|
-
final_new = current_effective_new_text.substring(
|
|
4861
|
-
actual_doc_text.length
|
|
4862
|
-
);
|
|
5022
|
+
final_new = current_effective_new_text.substring(actual_doc_text.length);
|
|
4863
5023
|
effective_start_idx = start_idx + match_len;
|
|
4864
5024
|
} else {
|
|
4865
5025
|
const [prefix_len, suffix_len] = trim_common_context(
|
|
@@ -4871,68 +5031,84 @@ var RedlineEngine = class {
|
|
|
4871
5031
|
final_target = actual_doc_text.substring(prefix_len, t_end);
|
|
4872
5032
|
final_new = current_effective_new_text.substring(prefix_len, n_end);
|
|
4873
5033
|
effective_start_idx = start_idx + prefix_len;
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
if (
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
5034
|
+
}
|
|
5035
|
+
if (has_markdown) {
|
|
5036
|
+
if (!final_target && final_new) {
|
|
5037
|
+
effective_op = "INSERTION";
|
|
5038
|
+
} else if (final_target && !final_new) {
|
|
5039
|
+
effective_op = "DELETION";
|
|
5040
|
+
} else if (final_target && final_new) {
|
|
5041
|
+
effective_op = "MODIFICATION";
|
|
5042
|
+
} else {
|
|
5043
|
+
all_sub_edits.push({
|
|
5044
|
+
type: "modify",
|
|
5045
|
+
target_text: final_target,
|
|
5046
|
+
new_text: final_new,
|
|
5047
|
+
comment: edit.comment,
|
|
5048
|
+
_match_start_index: effective_start_idx,
|
|
5049
|
+
_internal_op: "COMMENT_ONLY",
|
|
5050
|
+
_active_mapper_ref: active_mapper
|
|
5051
|
+
});
|
|
5052
|
+
continue;
|
|
5053
|
+
}
|
|
5054
|
+
all_sub_edits.push({
|
|
5055
|
+
type: "modify",
|
|
5056
|
+
target_text: final_target,
|
|
5057
|
+
new_text: final_new,
|
|
5058
|
+
comment: edit.comment,
|
|
5059
|
+
_resolved_start_idx: effective_start_idx,
|
|
5060
|
+
_match_start_index: effective_start_idx,
|
|
5061
|
+
_internal_op: effective_op,
|
|
5062
|
+
_active_mapper_ref: active_mapper
|
|
5063
|
+
});
|
|
5064
|
+
continue;
|
|
5065
|
+
}
|
|
5066
|
+
const target_segs = actual_doc_text.split("\n\n");
|
|
5067
|
+
const new_segs = current_effective_new_text.split("\n\n");
|
|
5068
|
+
if (actual_doc_text.includes("\n\n") && target_segs.length === new_segs.length) {
|
|
5069
|
+
const split_sub_edits = [];
|
|
5070
|
+
let seg_offset = start_idx;
|
|
5071
|
+
let comment_assigned = false;
|
|
5072
|
+
for (let k = 0; k < target_segs.length; k++) {
|
|
5073
|
+
const t_seg = target_segs[k];
|
|
5074
|
+
const n_seg = new_segs[k];
|
|
5075
|
+
if (t_seg !== n_seg) {
|
|
5076
|
+
const seg_comment = edit.comment && !comment_assigned ? edit.comment : null;
|
|
5077
|
+
const seg_sub_edits = this._word_diff_sub_edits(
|
|
5078
|
+
t_seg,
|
|
5079
|
+
n_seg,
|
|
5080
|
+
seg_offset,
|
|
5081
|
+
seg_comment,
|
|
5082
|
+
false,
|
|
5083
|
+
active_mapper
|
|
5084
|
+
);
|
|
5085
|
+
if (seg_sub_edits.some((se) => se.comment !== null && se.comment !== void 0)) {
|
|
5086
|
+
comment_assigned = true;
|
|
5087
|
+
}
|
|
5088
|
+
for (const se of seg_sub_edits) {
|
|
5089
|
+
se._split_group_id = start_idx;
|
|
5090
|
+
split_sub_edits.push(se);
|
|
4914
5091
|
}
|
|
4915
|
-
seg_offset += t_seg.length + 2;
|
|
4916
|
-
}
|
|
4917
|
-
if (split_sub_edits.length > 0) {
|
|
4918
|
-
for (const sub of split_sub_edits) all_sub_edits.push(sub);
|
|
4919
|
-
continue;
|
|
4920
5092
|
}
|
|
5093
|
+
seg_offset += t_seg.length + 2;
|
|
5094
|
+
}
|
|
5095
|
+
if (split_sub_edits.length > 0) {
|
|
5096
|
+
for (const sub of split_sub_edits) all_sub_edits.push(sub);
|
|
5097
|
+
continue;
|
|
4921
5098
|
}
|
|
4922
|
-
if (!final_target && final_new) effective_op = "INSERTION";
|
|
4923
|
-
else if (final_target && !final_new) effective_op = "DELETION";
|
|
4924
|
-
else if (final_target && final_new) effective_op = "MODIFICATION";
|
|
4925
|
-
else effective_op = "COMMENT_ONLY";
|
|
4926
5099
|
}
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
5100
|
+
const sub_edits = this._word_diff_sub_edits(
|
|
5101
|
+
actual_doc_text,
|
|
5102
|
+
current_effective_new_text,
|
|
5103
|
+
start_idx,
|
|
5104
|
+
edit.comment,
|
|
5105
|
+
false,
|
|
5106
|
+
active_mapper
|
|
5107
|
+
);
|
|
5108
|
+
for (const se of sub_edits) {
|
|
5109
|
+
se._split_group_id = start_idx;
|
|
5110
|
+
all_sub_edits.push(se);
|
|
5111
|
+
}
|
|
4936
5112
|
}
|
|
4937
5113
|
if (all_sub_edits.length === 0) return null;
|
|
4938
5114
|
if (match_mode === "all" || all_sub_edits.length > 1) return all_sub_edits;
|
|
@@ -4946,7 +5122,7 @@ var RedlineEngine = class {
|
|
|
4946
5122
|
* our replacement <w:ins> lands as a sibling, so we never nest <w:ins> in
|
|
4947
5123
|
* <w:ins>.
|
|
4948
5124
|
*/
|
|
4949
|
-
_insert_and_split_ins(parent_ins,
|
|
5125
|
+
_insert_and_split_ins(parent_ins, anchor, new_elem, split_before = false) {
|
|
4950
5126
|
const grandparent = parent_ins.parentNode;
|
|
4951
5127
|
if (!grandparent) return;
|
|
4952
5128
|
const left = parent_ins.cloneNode(false);
|
|
@@ -4954,9 +5130,10 @@ var RedlineEngine = class {
|
|
|
4954
5130
|
let toRight = false;
|
|
4955
5131
|
for (const kid of Array.from(parent_ins.childNodes)) {
|
|
4956
5132
|
parent_ins.removeChild(kid);
|
|
5133
|
+
if (split_before && kid === anchor) toRight = true;
|
|
4957
5134
|
if (!toRight) {
|
|
4958
5135
|
left.appendChild(kid);
|
|
4959
|
-
if (kid ===
|
|
5136
|
+
if (kid === anchor) toRight = true;
|
|
4960
5137
|
} else {
|
|
4961
5138
|
right.appendChild(kid);
|
|
4962
5139
|
}
|
|
@@ -4972,6 +5149,15 @@ var RedlineEngine = class {
|
|
|
4972
5149
|
const active_mapper = edit._active_mapper_ref || this.mapper;
|
|
4973
5150
|
const start_idx = edit._resolved_start_idx !== void 0 && edit._resolved_start_idx !== null ? edit._resolved_start_idx : edit._match_start_index || 0;
|
|
4974
5151
|
const length = edit.target_text ? edit.target_text.length : 0;
|
|
5152
|
+
if (op === void 0 || op === null) {
|
|
5153
|
+
if (!edit.target_text && edit.new_text) {
|
|
5154
|
+
op = "INSERTION";
|
|
5155
|
+
} else if (edit.target_text && !edit.new_text) {
|
|
5156
|
+
op = "DELETION";
|
|
5157
|
+
} else {
|
|
5158
|
+
op = "MODIFICATION";
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
4975
5161
|
if (op === "STYLE_ONLY" || op === "STYLE_AND_TEXT") {
|
|
4976
5162
|
const [anchor_run, anchor_para] = active_mapper.get_insertion_anchor(
|
|
4977
5163
|
start_idx,
|
|
@@ -5175,17 +5361,26 @@ var RedlineEngine = class {
|
|
|
5175
5361
|
if (is_inline_first) {
|
|
5176
5362
|
if (anchor_run) {
|
|
5177
5363
|
const anchor_parent = anchor_run._element.parentNode;
|
|
5364
|
+
const before_anchor = start_idx === 0;
|
|
5178
5365
|
if (anchor_parent && anchor_parent.tagName === "w:ins") {
|
|
5179
5366
|
this._insert_and_split_ins(
|
|
5180
5367
|
anchor_parent,
|
|
5181
5368
|
anchor_run._element,
|
|
5182
|
-
result.first_node
|
|
5369
|
+
result.first_node,
|
|
5370
|
+
before_anchor
|
|
5183
5371
|
);
|
|
5372
|
+
} else if (before_anchor && anchor_parent) {
|
|
5373
|
+
anchor_parent.insertBefore(result.first_node, anchor_run._element);
|
|
5184
5374
|
} else {
|
|
5185
5375
|
insertAfter(result.first_node, anchor_run._element);
|
|
5186
5376
|
}
|
|
5187
5377
|
} else if (anchor_para) {
|
|
5188
|
-
anchor_para._element
|
|
5378
|
+
const para_el = anchor_para._element;
|
|
5379
|
+
let ref = para_el.firstChild;
|
|
5380
|
+
while (ref && ref.tagName === "w:pPr") {
|
|
5381
|
+
ref = ref.nextSibling;
|
|
5382
|
+
}
|
|
5383
|
+
para_el.insertBefore(result.first_node, ref);
|
|
5189
5384
|
}
|
|
5190
5385
|
}
|
|
5191
5386
|
if (edit.comment) {
|