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