@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.d.cts
CHANGED
|
@@ -196,6 +196,7 @@ declare class RedlineEngine {
|
|
|
196
196
|
* and the edit succeeds despite it. Mirrors the Python engine.
|
|
197
197
|
*/
|
|
198
198
|
private _check_punctuation_warning;
|
|
199
|
+
private _word_diff_sub_edits;
|
|
199
200
|
/**
|
|
200
201
|
* Best-effort "did you mean" hint for a failed target. The common loop trap
|
|
201
202
|
* (observed in the field) is an anchored regex like `^\( x \)$` against a
|
package/dist/index.d.ts
CHANGED
|
@@ -196,6 +196,7 @@ declare class RedlineEngine {
|
|
|
196
196
|
* and the edit succeeds despite it. Mirrors the Python engine.
|
|
197
197
|
*/
|
|
198
198
|
private _check_punctuation_warning;
|
|
199
|
+
private _word_diff_sub_edits;
|
|
199
200
|
/**
|
|
200
201
|
* Best-effort "did you mean" hint for a failed target. The common loop trap
|
|
201
202
|
* (observed in the field) is an anchored regex like `^\( x \)$` against a
|
package/dist/index.js
CHANGED
|
@@ -3030,6 +3030,76 @@ var RedlineEngine = class {
|
|
|
3030
3030
|
}
|
|
3031
3031
|
return null;
|
|
3032
3032
|
}
|
|
3033
|
+
_word_diff_sub_edits(target_str, new_str, base_offset, parent_comment = null, is_table = false, active_mapper = null) {
|
|
3034
|
+
let raw_sub_edits = [];
|
|
3035
|
+
try {
|
|
3036
|
+
raw_sub_edits = generate_edits_from_text(target_str, new_str);
|
|
3037
|
+
console.log("_word_diff_sub_edits RAW_SUB_EDITS:", JSON.stringify(raw_sub_edits, null, 2));
|
|
3038
|
+
} catch (e) {
|
|
3039
|
+
console.warn("generate_edits_from_text failed, falling back to wholesale edit", e);
|
|
3040
|
+
raw_sub_edits = [];
|
|
3041
|
+
}
|
|
3042
|
+
if (!raw_sub_edits || raw_sub_edits.length === 0) {
|
|
3043
|
+
const fallback_edit = {
|
|
3044
|
+
type: "modify",
|
|
3045
|
+
target_text: target_str,
|
|
3046
|
+
new_text: new_str,
|
|
3047
|
+
comment: parent_comment
|
|
3048
|
+
};
|
|
3049
|
+
fallback_edit._resolved_start_idx = base_offset;
|
|
3050
|
+
fallback_edit._match_start_index = base_offset;
|
|
3051
|
+
fallback_edit._active_mapper_ref = active_mapper;
|
|
3052
|
+
if (is_table) {
|
|
3053
|
+
fallback_edit._is_table_edit = true;
|
|
3054
|
+
}
|
|
3055
|
+
if (target_str === new_str) {
|
|
3056
|
+
fallback_edit._internal_op = "COMMENT_ONLY";
|
|
3057
|
+
} else if (!target_str && new_str) {
|
|
3058
|
+
fallback_edit._internal_op = "INSERTION";
|
|
3059
|
+
} else if (target_str && !new_str) {
|
|
3060
|
+
fallback_edit._internal_op = "DELETION";
|
|
3061
|
+
} else if (target_str && new_str) {
|
|
3062
|
+
fallback_edit._internal_op = "MODIFICATION";
|
|
3063
|
+
} else {
|
|
3064
|
+
fallback_edit._internal_op = "COMMENT_ONLY";
|
|
3065
|
+
}
|
|
3066
|
+
return [fallback_edit];
|
|
3067
|
+
}
|
|
3068
|
+
const sub_edits = [];
|
|
3069
|
+
let comment_assigned = false;
|
|
3070
|
+
for (const raw_edit of raw_sub_edits) {
|
|
3071
|
+
const sub_start = base_offset + (raw_edit._match_start_index || 0);
|
|
3072
|
+
const should_attach_comment = parent_comment !== null && !comment_assigned;
|
|
3073
|
+
if (should_attach_comment) {
|
|
3074
|
+
comment_assigned = true;
|
|
3075
|
+
}
|
|
3076
|
+
const sub_edit = {
|
|
3077
|
+
type: "modify",
|
|
3078
|
+
target_text: raw_edit.target_text,
|
|
3079
|
+
new_text: raw_edit.new_text,
|
|
3080
|
+
comment: should_attach_comment ? parent_comment : null
|
|
3081
|
+
};
|
|
3082
|
+
sub_edit._resolved_start_idx = sub_start;
|
|
3083
|
+
sub_edit._match_start_index = sub_start;
|
|
3084
|
+
sub_edit._active_mapper_ref = active_mapper;
|
|
3085
|
+
if (is_table) {
|
|
3086
|
+
sub_edit._is_table_edit = true;
|
|
3087
|
+
}
|
|
3088
|
+
const t_val = raw_edit.target_text;
|
|
3089
|
+
const n_val = raw_edit.new_text;
|
|
3090
|
+
if (!t_val && n_val) {
|
|
3091
|
+
sub_edit._internal_op = "INSERTION";
|
|
3092
|
+
} else if (t_val && !n_val) {
|
|
3093
|
+
sub_edit._internal_op = "DELETION";
|
|
3094
|
+
} else if (t_val && n_val) {
|
|
3095
|
+
sub_edit._internal_op = "MODIFICATION";
|
|
3096
|
+
} else {
|
|
3097
|
+
sub_edit._internal_op = "COMMENT_ONLY";
|
|
3098
|
+
}
|
|
3099
|
+
sub_edits.push(sub_edit);
|
|
3100
|
+
}
|
|
3101
|
+
return sub_edits;
|
|
3102
|
+
}
|
|
3033
3103
|
/**
|
|
3034
3104
|
* Best-effort "did you mean" hint for a failed target. The common loop trap
|
|
3035
3105
|
* (observed in the field) is an anchored regex like `^\( x \)$` against a
|
|
@@ -3959,6 +4029,8 @@ var RedlineEngine = class {
|
|
|
3959
4029
|
continue;
|
|
3960
4030
|
}
|
|
3961
4031
|
if (!edit.target_text) continue;
|
|
4032
|
+
if (edit._match_start_index !== void 0 && edit._match_start_index !== null || edit._resolved_start_idx !== void 0 && edit._resolved_start_idx !== null)
|
|
4033
|
+
continue;
|
|
3962
4034
|
const is_regex = edit.regex || false;
|
|
3963
4035
|
const match_mode = edit.match_mode || "strict";
|
|
3964
4036
|
let matches = this.mapper.find_all_match_indices(
|
|
@@ -4262,16 +4334,31 @@ var RedlineEngine = class {
|
|
|
4262
4334
|
let applied_edits = 0;
|
|
4263
4335
|
let skipped_edits = 0;
|
|
4264
4336
|
if (edits.length > 0) {
|
|
4337
|
+
const pinned_idx = (e) => {
|
|
4338
|
+
if (e._resolved_start_idx !== void 0 && e._resolved_start_idx !== null)
|
|
4339
|
+
return e._resolved_start_idx;
|
|
4340
|
+
if (e._match_start_index !== void 0 && e._match_start_index !== null)
|
|
4341
|
+
return e._match_start_index;
|
|
4342
|
+
return null;
|
|
4343
|
+
};
|
|
4344
|
+
const ordered_edits = edits.map((edit, i) => ({ edit, i })).sort((a, b) => {
|
|
4345
|
+
const ka = pinned_idx(a.edit);
|
|
4346
|
+
const kb = pinned_idx(b.edit);
|
|
4347
|
+
if (ka === null && kb === null) return a.i - b.i;
|
|
4348
|
+
if (ka === null) return 1;
|
|
4349
|
+
if (kb === null) return -1;
|
|
4350
|
+
return kb - ka || a.i - b.i;
|
|
4351
|
+
});
|
|
4265
4352
|
if (dry_run_mode) {
|
|
4266
|
-
|
|
4267
|
-
|
|
4353
|
+
const reports_by_input = new Array(edits.length);
|
|
4354
|
+
for (const { edit, i } of ordered_edits) {
|
|
4268
4355
|
const single_errors = this.validate_edits([edit], i);
|
|
4269
4356
|
if (single_errors.length > 0) {
|
|
4270
4357
|
skipped_edits++;
|
|
4271
4358
|
const warning = this._check_punctuation_warning(
|
|
4272
4359
|
edit.target_text || ""
|
|
4273
4360
|
);
|
|
4274
|
-
|
|
4361
|
+
reports_by_input[i] = {
|
|
4275
4362
|
status: "failed",
|
|
4276
4363
|
target_text: edit.target_text || "",
|
|
4277
4364
|
new_text: edit.new_text || "",
|
|
@@ -4279,14 +4366,14 @@ var RedlineEngine = class {
|
|
|
4279
4366
|
error: single_errors[0],
|
|
4280
4367
|
critic_markup: null,
|
|
4281
4368
|
clean_text: null
|
|
4282
|
-
}
|
|
4369
|
+
};
|
|
4283
4370
|
continue;
|
|
4284
4371
|
}
|
|
4285
4372
|
const res = this.apply_edits([edit], page_offsets);
|
|
4286
4373
|
if (edit._applied_status) {
|
|
4287
4374
|
applied_edits++;
|
|
4288
4375
|
const previews = this._build_edit_context_previews(edit);
|
|
4289
|
-
|
|
4376
|
+
reports_by_input[i] = {
|
|
4290
4377
|
status: "applied",
|
|
4291
4378
|
target_text: edit.target_text || "",
|
|
4292
4379
|
new_text: edit.new_text || "",
|
|
@@ -4298,7 +4385,7 @@ var RedlineEngine = class {
|
|
|
4298
4385
|
heading_path: edit._heading_path || "",
|
|
4299
4386
|
occurrences_modified: edit._occurrences_modified || 0,
|
|
4300
4387
|
match_mode: edit.match_mode || "strict"
|
|
4301
|
-
}
|
|
4388
|
+
};
|
|
4302
4389
|
this.mapper = new DocumentMapper(this.doc);
|
|
4303
4390
|
this.clean_mapper = null;
|
|
4304
4391
|
} else {
|
|
@@ -4307,7 +4394,7 @@ var RedlineEngine = class {
|
|
|
4307
4394
|
const warning = this._check_punctuation_warning(
|
|
4308
4395
|
edit.target_text || ""
|
|
4309
4396
|
);
|
|
4310
|
-
|
|
4397
|
+
reports_by_input[i] = {
|
|
4311
4398
|
status: "failed",
|
|
4312
4399
|
target_text: edit.target_text || "",
|
|
4313
4400
|
new_text: edit.new_text || "",
|
|
@@ -4315,16 +4402,16 @@ var RedlineEngine = class {
|
|
|
4315
4402
|
error: error_msg,
|
|
4316
4403
|
critic_markup: null,
|
|
4317
4404
|
clean_text: null
|
|
4318
|
-
}
|
|
4405
|
+
};
|
|
4319
4406
|
}
|
|
4320
4407
|
}
|
|
4408
|
+
edits_reports.push(...reports_by_input);
|
|
4321
4409
|
} else {
|
|
4322
4410
|
const snapshot = takeSnapshot(this.doc);
|
|
4323
4411
|
const originalCurrentId = this.current_id;
|
|
4324
4412
|
try {
|
|
4325
4413
|
const sequential_errors = [];
|
|
4326
|
-
for (
|
|
4327
|
-
const edit = edits[i];
|
|
4414
|
+
for (const { edit, i } of ordered_edits) {
|
|
4328
4415
|
const single_errors = this.validate_edits([edit], i);
|
|
4329
4416
|
if (single_errors.length > 0) {
|
|
4330
4417
|
sequential_errors.push(...single_errors);
|
|
@@ -4492,7 +4579,8 @@ var RedlineEngine = class {
|
|
|
4492
4579
|
}
|
|
4493
4580
|
let success = false;
|
|
4494
4581
|
if (edit.type === "modify") {
|
|
4495
|
-
|
|
4582
|
+
const rebuild = edit._split_group_id !== void 0 && edit._split_group_id !== null;
|
|
4583
|
+
success = this._apply_single_edit_indexed(edit, orig_new, rebuild);
|
|
4496
4584
|
} else if (edit.type === "insert_row" || edit.type === "delete_row") {
|
|
4497
4585
|
success = this._apply_table_edit(edit, false);
|
|
4498
4586
|
}
|
|
@@ -4800,15 +4888,87 @@ var RedlineEngine = class {
|
|
|
4800
4888
|
});
|
|
4801
4889
|
continue;
|
|
4802
4890
|
}
|
|
4891
|
+
let overlaps_virtual_pipe = false;
|
|
4892
|
+
if (active_mapper) {
|
|
4893
|
+
overlaps_virtual_pipe = active_mapper.spans.some(
|
|
4894
|
+
(s) => s.text === " | " && (s.run === null || s.run === void 0) && s.start < start_idx + match_len && s.end > start_idx
|
|
4895
|
+
);
|
|
4896
|
+
}
|
|
4897
|
+
if (overlaps_virtual_pipe) {
|
|
4898
|
+
const actual_cells = actual_doc_text.split("|");
|
|
4899
|
+
const new_cells = current_effective_new_text.split("|");
|
|
4900
|
+
if (actual_cells.length === new_cells.length && actual_cells.length > 1) {
|
|
4901
|
+
const sub_edits2 = [];
|
|
4902
|
+
let search_offset = start_idx;
|
|
4903
|
+
let target_comment_idx = 0;
|
|
4904
|
+
for (let idx = 0; idx < actual_cells.length; idx++) {
|
|
4905
|
+
if (actual_cells[idx].trim() !== new_cells[idx].trim()) {
|
|
4906
|
+
target_comment_idx = idx;
|
|
4907
|
+
break;
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
for (let cell_idx = 0; cell_idx < actual_cells.length; cell_idx++) {
|
|
4911
|
+
const a_cell = actual_cells[cell_idx];
|
|
4912
|
+
const n_cell = new_cells[cell_idx];
|
|
4913
|
+
const a_clean = a_cell.trim();
|
|
4914
|
+
const n_clean = n_cell.trim();
|
|
4915
|
+
let actual_start = search_offset;
|
|
4916
|
+
if (a_clean) {
|
|
4917
|
+
actual_start = this.mapper.full_text.indexOf(a_clean, search_offset);
|
|
4918
|
+
if (actual_start === -1 || actual_start > search_offset + 10) {
|
|
4919
|
+
actual_start = search_offset;
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
const should_attach_comment = edit.comment !== null && edit.comment !== void 0 && cell_idx === target_comment_idx;
|
|
4923
|
+
if (a_clean !== n_clean || should_attach_comment) {
|
|
4924
|
+
const cell_sub_edits = this._word_diff_sub_edits(
|
|
4925
|
+
a_clean,
|
|
4926
|
+
n_clean,
|
|
4927
|
+
actual_start,
|
|
4928
|
+
should_attach_comment ? edit.comment : null,
|
|
4929
|
+
true,
|
|
4930
|
+
active_mapper
|
|
4931
|
+
);
|
|
4932
|
+
for (const se of cell_sub_edits) {
|
|
4933
|
+
se._original_target_text = edit.target_text;
|
|
4934
|
+
se._split_group_id = start_idx;
|
|
4935
|
+
sub_edits2.push(se);
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
if (a_clean) {
|
|
4939
|
+
search_offset = actual_start + a_clean.length;
|
|
4940
|
+
}
|
|
4941
|
+
const next_pipe = this.mapper.full_text.indexOf(" | ", search_offset);
|
|
4942
|
+
if (next_pipe !== -1 && next_pipe <= search_offset + 10) {
|
|
4943
|
+
search_offset = next_pipe + 3;
|
|
4944
|
+
} else {
|
|
4945
|
+
search_offset += a_cell.length + 1;
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4948
|
+
for (const sub of sub_edits2) {
|
|
4949
|
+
all_sub_edits.push(sub);
|
|
4950
|
+
}
|
|
4951
|
+
continue;
|
|
4952
|
+
} else {
|
|
4953
|
+
throw new BatchValidationError([
|
|
4954
|
+
`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).`
|
|
4955
|
+
]);
|
|
4956
|
+
}
|
|
4957
|
+
}
|
|
4958
|
+
let has_markdown = false;
|
|
4959
|
+
if (edit.target_text && (edit.target_text.includes("**") || edit.target_text.includes("_"))) {
|
|
4960
|
+
has_markdown = true;
|
|
4961
|
+
}
|
|
4962
|
+
if (current_effective_new_text && (current_effective_new_text.includes("**") || current_effective_new_text.includes("_"))) {
|
|
4963
|
+
has_markdown = true;
|
|
4964
|
+
}
|
|
4803
4965
|
let effective_op = "";
|
|
4804
4966
|
let final_target = "";
|
|
4805
4967
|
let final_new = "";
|
|
4806
4968
|
let effective_start_idx = start_idx;
|
|
4807
4969
|
if (current_effective_new_text.startsWith(actual_doc_text)) {
|
|
4808
4970
|
effective_op = "INSERTION";
|
|
4809
|
-
final_new = current_effective_new_text.substring(
|
|
4810
|
-
actual_doc_text.length
|
|
4811
|
-
);
|
|
4971
|
+
final_new = current_effective_new_text.substring(actual_doc_text.length);
|
|
4812
4972
|
effective_start_idx = start_idx + match_len;
|
|
4813
4973
|
} else {
|
|
4814
4974
|
const [prefix_len, suffix_len] = trim_common_context(
|
|
@@ -4820,68 +4980,84 @@ var RedlineEngine = class {
|
|
|
4820
4980
|
final_target = actual_doc_text.substring(prefix_len, t_end);
|
|
4821
4981
|
final_new = current_effective_new_text.substring(prefix_len, n_end);
|
|
4822
4982
|
effective_start_idx = start_idx + prefix_len;
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
if (
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4983
|
+
}
|
|
4984
|
+
if (has_markdown) {
|
|
4985
|
+
if (!final_target && final_new) {
|
|
4986
|
+
effective_op = "INSERTION";
|
|
4987
|
+
} else if (final_target && !final_new) {
|
|
4988
|
+
effective_op = "DELETION";
|
|
4989
|
+
} else if (final_target && final_new) {
|
|
4990
|
+
effective_op = "MODIFICATION";
|
|
4991
|
+
} else {
|
|
4992
|
+
all_sub_edits.push({
|
|
4993
|
+
type: "modify",
|
|
4994
|
+
target_text: final_target,
|
|
4995
|
+
new_text: final_new,
|
|
4996
|
+
comment: edit.comment,
|
|
4997
|
+
_match_start_index: effective_start_idx,
|
|
4998
|
+
_internal_op: "COMMENT_ONLY",
|
|
4999
|
+
_active_mapper_ref: active_mapper
|
|
5000
|
+
});
|
|
5001
|
+
continue;
|
|
5002
|
+
}
|
|
5003
|
+
all_sub_edits.push({
|
|
5004
|
+
type: "modify",
|
|
5005
|
+
target_text: final_target,
|
|
5006
|
+
new_text: final_new,
|
|
5007
|
+
comment: edit.comment,
|
|
5008
|
+
_resolved_start_idx: effective_start_idx,
|
|
5009
|
+
_match_start_index: effective_start_idx,
|
|
5010
|
+
_internal_op: effective_op,
|
|
5011
|
+
_active_mapper_ref: active_mapper
|
|
5012
|
+
});
|
|
5013
|
+
continue;
|
|
5014
|
+
}
|
|
5015
|
+
const target_segs = actual_doc_text.split("\n\n");
|
|
5016
|
+
const new_segs = current_effective_new_text.split("\n\n");
|
|
5017
|
+
if (actual_doc_text.includes("\n\n") && target_segs.length === new_segs.length) {
|
|
5018
|
+
const split_sub_edits = [];
|
|
5019
|
+
let seg_offset = start_idx;
|
|
5020
|
+
let comment_assigned = false;
|
|
5021
|
+
for (let k = 0; k < target_segs.length; k++) {
|
|
5022
|
+
const t_seg = target_segs[k];
|
|
5023
|
+
const n_seg = new_segs[k];
|
|
5024
|
+
if (t_seg !== n_seg) {
|
|
5025
|
+
const seg_comment = edit.comment && !comment_assigned ? edit.comment : null;
|
|
5026
|
+
const seg_sub_edits = this._word_diff_sub_edits(
|
|
5027
|
+
t_seg,
|
|
5028
|
+
n_seg,
|
|
5029
|
+
seg_offset,
|
|
5030
|
+
seg_comment,
|
|
5031
|
+
false,
|
|
5032
|
+
active_mapper
|
|
5033
|
+
);
|
|
5034
|
+
if (seg_sub_edits.some((se) => se.comment !== null && se.comment !== void 0)) {
|
|
5035
|
+
comment_assigned = true;
|
|
5036
|
+
}
|
|
5037
|
+
for (const se of seg_sub_edits) {
|
|
5038
|
+
se._split_group_id = start_idx;
|
|
5039
|
+
split_sub_edits.push(se);
|
|
4863
5040
|
}
|
|
4864
|
-
seg_offset += t_seg.length + 2;
|
|
4865
|
-
}
|
|
4866
|
-
if (split_sub_edits.length > 0) {
|
|
4867
|
-
for (const sub of split_sub_edits) all_sub_edits.push(sub);
|
|
4868
|
-
continue;
|
|
4869
5041
|
}
|
|
5042
|
+
seg_offset += t_seg.length + 2;
|
|
5043
|
+
}
|
|
5044
|
+
if (split_sub_edits.length > 0) {
|
|
5045
|
+
for (const sub of split_sub_edits) all_sub_edits.push(sub);
|
|
5046
|
+
continue;
|
|
4870
5047
|
}
|
|
4871
|
-
if (!final_target && final_new) effective_op = "INSERTION";
|
|
4872
|
-
else if (final_target && !final_new) effective_op = "DELETION";
|
|
4873
|
-
else if (final_target && final_new) effective_op = "MODIFICATION";
|
|
4874
|
-
else effective_op = "COMMENT_ONLY";
|
|
4875
5048
|
}
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
5049
|
+
const sub_edits = this._word_diff_sub_edits(
|
|
5050
|
+
actual_doc_text,
|
|
5051
|
+
current_effective_new_text,
|
|
5052
|
+
start_idx,
|
|
5053
|
+
edit.comment,
|
|
5054
|
+
false,
|
|
5055
|
+
active_mapper
|
|
5056
|
+
);
|
|
5057
|
+
for (const se of sub_edits) {
|
|
5058
|
+
se._split_group_id = start_idx;
|
|
5059
|
+
all_sub_edits.push(se);
|
|
5060
|
+
}
|
|
4885
5061
|
}
|
|
4886
5062
|
if (all_sub_edits.length === 0) return null;
|
|
4887
5063
|
if (match_mode === "all" || all_sub_edits.length > 1) return all_sub_edits;
|
|
@@ -4895,7 +5071,7 @@ var RedlineEngine = class {
|
|
|
4895
5071
|
* our replacement <w:ins> lands as a sibling, so we never nest <w:ins> in
|
|
4896
5072
|
* <w:ins>.
|
|
4897
5073
|
*/
|
|
4898
|
-
_insert_and_split_ins(parent_ins,
|
|
5074
|
+
_insert_and_split_ins(parent_ins, anchor, new_elem, split_before = false) {
|
|
4899
5075
|
const grandparent = parent_ins.parentNode;
|
|
4900
5076
|
if (!grandparent) return;
|
|
4901
5077
|
const left = parent_ins.cloneNode(false);
|
|
@@ -4903,9 +5079,10 @@ var RedlineEngine = class {
|
|
|
4903
5079
|
let toRight = false;
|
|
4904
5080
|
for (const kid of Array.from(parent_ins.childNodes)) {
|
|
4905
5081
|
parent_ins.removeChild(kid);
|
|
5082
|
+
if (split_before && kid === anchor) toRight = true;
|
|
4906
5083
|
if (!toRight) {
|
|
4907
5084
|
left.appendChild(kid);
|
|
4908
|
-
if (kid ===
|
|
5085
|
+
if (kid === anchor) toRight = true;
|
|
4909
5086
|
} else {
|
|
4910
5087
|
right.appendChild(kid);
|
|
4911
5088
|
}
|
|
@@ -4921,6 +5098,15 @@ var RedlineEngine = class {
|
|
|
4921
5098
|
const active_mapper = edit._active_mapper_ref || this.mapper;
|
|
4922
5099
|
const start_idx = edit._resolved_start_idx !== void 0 && edit._resolved_start_idx !== null ? edit._resolved_start_idx : edit._match_start_index || 0;
|
|
4923
5100
|
const length = edit.target_text ? edit.target_text.length : 0;
|
|
5101
|
+
if (op === void 0 || op === null) {
|
|
5102
|
+
if (!edit.target_text && edit.new_text) {
|
|
5103
|
+
op = "INSERTION";
|
|
5104
|
+
} else if (edit.target_text && !edit.new_text) {
|
|
5105
|
+
op = "DELETION";
|
|
5106
|
+
} else {
|
|
5107
|
+
op = "MODIFICATION";
|
|
5108
|
+
}
|
|
5109
|
+
}
|
|
4924
5110
|
if (op === "STYLE_ONLY" || op === "STYLE_AND_TEXT") {
|
|
4925
5111
|
const [anchor_run, anchor_para] = active_mapper.get_insertion_anchor(
|
|
4926
5112
|
start_idx,
|
|
@@ -5124,17 +5310,26 @@ var RedlineEngine = class {
|
|
|
5124
5310
|
if (is_inline_first) {
|
|
5125
5311
|
if (anchor_run) {
|
|
5126
5312
|
const anchor_parent = anchor_run._element.parentNode;
|
|
5313
|
+
const before_anchor = start_idx === 0;
|
|
5127
5314
|
if (anchor_parent && anchor_parent.tagName === "w:ins") {
|
|
5128
5315
|
this._insert_and_split_ins(
|
|
5129
5316
|
anchor_parent,
|
|
5130
5317
|
anchor_run._element,
|
|
5131
|
-
result.first_node
|
|
5318
|
+
result.first_node,
|
|
5319
|
+
before_anchor
|
|
5132
5320
|
);
|
|
5321
|
+
} else if (before_anchor && anchor_parent) {
|
|
5322
|
+
anchor_parent.insertBefore(result.first_node, anchor_run._element);
|
|
5133
5323
|
} else {
|
|
5134
5324
|
insertAfter(result.first_node, anchor_run._element);
|
|
5135
5325
|
}
|
|
5136
5326
|
} else if (anchor_para) {
|
|
5137
|
-
anchor_para._element
|
|
5327
|
+
const para_el = anchor_para._element;
|
|
5328
|
+
let ref = para_el.firstChild;
|
|
5329
|
+
while (ref && ref.tagName === "w:pPr") {
|
|
5330
|
+
ref = ref.nextSibling;
|
|
5331
|
+
}
|
|
5332
|
+
para_el.insertBefore(result.first_node, ref);
|
|
5138
5333
|
}
|
|
5139
5334
|
}
|
|
5140
5335
|
if (edit.comment) {
|