@adeu/core 1.17.2 → 1.18.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 +227 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +227 -80
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine.bugs.test.ts +12 -14
- package/src/engine.issue23.test.ts +23 -18
- package/src/engine.ts +329 -91
- package/src/reject_and_nested_redline.test.ts +137 -0
- package/src/repro.report.test.ts +11 -9
- package/src/repro_qa_report_v3.test.ts +19 -27
- package/src/repro_report_boundary_failures.test.ts +108 -0
package/dist/index.cjs
CHANGED
|
@@ -3346,6 +3346,93 @@ var RedlineEngine = class {
|
|
|
3346
3346
|
}
|
|
3347
3347
|
}
|
|
3348
3348
|
}
|
|
3349
|
+
/**
|
|
3350
|
+
* Revert every tracked change, returning the document to the state it had
|
|
3351
|
+
* before any revision was proposed. The exact inverse of
|
|
3352
|
+
* accept_all_revisions:
|
|
3353
|
+
*
|
|
3354
|
+
* - <w:ins> -> removed together with all of its content (the proposed
|
|
3355
|
+
* insertion never existed); an inserted row (<w:ins> in
|
|
3356
|
+
* <w:trPr>) drops the whole row.
|
|
3357
|
+
* - <w:del> -> unwrapped, restoring the original text (<w:delText> becomes
|
|
3358
|
+
* <w:t> again); a row-deletion mark in <w:trPr> is removed so
|
|
3359
|
+
* the row survives.
|
|
3360
|
+
* - paragraph-mark <w:del> in pPr/rPr -> removed, undoing a proposed merge.
|
|
3361
|
+
*
|
|
3362
|
+
* Comments are annotations, not revisions, so standalone comments are left in
|
|
3363
|
+
* place; only anchors stranded inside a rejected insertion are cleaned up.
|
|
3364
|
+
*
|
|
3365
|
+
* Insertions are reverted before deletions are restored so a deletion nested
|
|
3366
|
+
* inside a foreign author's insertion is removed wholesale with the insertion
|
|
3367
|
+
* — the contingent text disappears rather than being promoted to committed
|
|
3368
|
+
* body text.
|
|
3369
|
+
*
|
|
3370
|
+
* Known limitation: tracked paragraph STRUCTURE changes (a split recorded as a
|
|
3371
|
+
* pilcrow <w:ins>, or a merge recorded as a pilcrow <w:del>) are reverted only
|
|
3372
|
+
* to the extent of dropping/keeping the mark; the original paragraph boundary
|
|
3373
|
+
* is not reconstructed, because the merge protocol coalesces paragraphs
|
|
3374
|
+
* destructively at edit time. Reverting run-level insertions/deletions (the
|
|
3375
|
+
* common case) is exact. This limitation is shared with the Python engine.
|
|
3376
|
+
*/
|
|
3377
|
+
reject_all_revisions() {
|
|
3378
|
+
const parts_to_process = [this.doc.element];
|
|
3379
|
+
for (const part of this.doc.pkg.parts) {
|
|
3380
|
+
if (part === this.doc.part) continue;
|
|
3381
|
+
if (part.contentType.includes("wordprocessingml") && part.contentType.endsWith("+xml")) {
|
|
3382
|
+
parts_to_process.push(part._element);
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
for (const root_element of parts_to_process) {
|
|
3386
|
+
const insNodes = findAllDescendants(root_element, "w:ins");
|
|
3387
|
+
for (const ins of insNodes) {
|
|
3388
|
+
const parent = ins.parentNode;
|
|
3389
|
+
if (!parent) continue;
|
|
3390
|
+
this._clean_wrapping_comments(ins);
|
|
3391
|
+
this._delete_comments_in_element(ins);
|
|
3392
|
+
if (parent.tagName === "w:trPr") {
|
|
3393
|
+
const row = parent.parentNode;
|
|
3394
|
+
if (row && row.parentNode) {
|
|
3395
|
+
row.parentNode.removeChild(row);
|
|
3396
|
+
}
|
|
3397
|
+
} else {
|
|
3398
|
+
parent.removeChild(ins);
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
const pNodes = findAllDescendants(root_element, "w:p");
|
|
3402
|
+
for (const p of pNodes) {
|
|
3403
|
+
const pPr = findChild(p, "w:pPr");
|
|
3404
|
+
if (pPr) {
|
|
3405
|
+
const rPr = findChild(pPr, "w:rPr");
|
|
3406
|
+
const delMark = rPr ? findChild(rPr, "w:del") : null;
|
|
3407
|
+
if (rPr && delMark) {
|
|
3408
|
+
rPr.removeChild(delMark);
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
const delNodes = findAllDescendants(root_element, "w:del");
|
|
3413
|
+
for (const d of delNodes) {
|
|
3414
|
+
const parent = d.parentNode;
|
|
3415
|
+
if (!parent) continue;
|
|
3416
|
+
this._clean_wrapping_comments(d);
|
|
3417
|
+
if (parent.tagName === "w:trPr") {
|
|
3418
|
+
parent.removeChild(d);
|
|
3419
|
+
continue;
|
|
3420
|
+
}
|
|
3421
|
+
const delTexts = Array.from(d.getElementsByTagName("w:delText"));
|
|
3422
|
+
for (const dt of delTexts) {
|
|
3423
|
+
const t = d.ownerDocument.createElement("w:t");
|
|
3424
|
+
t.textContent = dt.textContent;
|
|
3425
|
+
if (dt.hasAttribute("xml:space"))
|
|
3426
|
+
t.setAttribute("xml:space", "preserve");
|
|
3427
|
+
dt.parentNode?.replaceChild(t, dt);
|
|
3428
|
+
}
|
|
3429
|
+
while (d.firstChild) {
|
|
3430
|
+
parent.insertBefore(d.firstChild, d);
|
|
3431
|
+
}
|
|
3432
|
+
parent.removeChild(d);
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3349
3436
|
_getNextId() {
|
|
3350
3437
|
this.current_id++;
|
|
3351
3438
|
return this.current_id.toString();
|
|
@@ -3993,29 +4080,36 @@ var RedlineEngine = class {
|
|
|
3993
4080
|
(edit.new_text || "").length - sfx
|
|
3994
4081
|
);
|
|
3995
4082
|
if (final_target.includes("\n\n")) {
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
if (
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4083
|
+
const balanced = matched.split("\n\n").length === (edit.new_text || "").split("\n\n").length;
|
|
4084
|
+
if (!balanced) {
|
|
4085
|
+
if (final_new.includes("\n\n")) {
|
|
4086
|
+
const parts = matched.split("\n\n");
|
|
4087
|
+
if (parts.length >= 2 && parts[0].trim() !== "" && parts[parts.length - 1].trim() !== "") {
|
|
4088
|
+
errors.push(
|
|
4089
|
+
`- Edit ${i + 1 + index_offset} Failed: target_text spans a paragraph boundary with body text on both sides. The paragraph break is a structural element, not literal text, so it cannot be replaced as a single span without corrupting the document. Split this into one edit per paragraph.`
|
|
4090
|
+
);
|
|
4091
|
+
}
|
|
4092
|
+
} else {
|
|
4093
|
+
const parts = final_target.split("\n\n");
|
|
4094
|
+
if (parts.length >= 2 && parts[0].trim() !== "" && parts[parts.length - 1].trim() !== "") {
|
|
4095
|
+
errors.push(
|
|
4096
|
+
`- Edit ${i + 1 + index_offset} Failed: target_text spans a paragraph boundary with body text on both sides. The paragraph break is a structural element, not literal text, so it cannot be replaced as a single span without corrupting the document. Split this into one edit per paragraph.`
|
|
4097
|
+
);
|
|
4098
|
+
}
|
|
4009
4099
|
}
|
|
4010
4100
|
}
|
|
4011
4101
|
}
|
|
4012
4102
|
}
|
|
4013
4103
|
for (const [start, length] of matches) {
|
|
4014
|
-
const spans =
|
|
4104
|
+
const spans = target_mapper.spans.filter(
|
|
4015
4105
|
(s) => s.end > start && s.start < start + length
|
|
4016
4106
|
);
|
|
4017
|
-
const
|
|
4107
|
+
const insAuthors = /* @__PURE__ */ new Set();
|
|
4108
|
+
const commentAuthors = /* @__PURE__ */ new Set();
|
|
4109
|
+
let hasNonForeignRealText = false;
|
|
4018
4110
|
for (const s of spans) {
|
|
4111
|
+
if (s.run === null) continue;
|
|
4112
|
+
let isForeignIns = false;
|
|
4019
4113
|
if (s.ins_id) {
|
|
4020
4114
|
const insNodes = findAllDescendants(
|
|
4021
4115
|
this.doc.element,
|
|
@@ -4024,24 +4118,32 @@ var RedlineEngine = class {
|
|
|
4024
4118
|
if (insNodes.length > 0) {
|
|
4025
4119
|
const auth = insNodes[0].getAttribute("w:author");
|
|
4026
4120
|
if (auth && auth !== this.author) {
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
if (is_lockout) {
|
|
4030
|
-
nestedAuthors.add(auth);
|
|
4031
|
-
}
|
|
4121
|
+
insAuthors.add(auth);
|
|
4122
|
+
isForeignIns = true;
|
|
4032
4123
|
}
|
|
4033
4124
|
}
|
|
4034
4125
|
}
|
|
4126
|
+
if (!isForeignIns) hasNonForeignRealText = true;
|
|
4127
|
+
}
|
|
4128
|
+
for (const s of spans) {
|
|
4035
4129
|
if (s.comment_ids) {
|
|
4036
4130
|
for (const cid of s.comment_ids) {
|
|
4037
4131
|
const c_data = this.mapper.comments_map[cid];
|
|
4038
4132
|
if (c_data && c_data.author && c_data.author !== this.author) {
|
|
4039
|
-
|
|
4133
|
+
commentAuthors.add(c_data.author);
|
|
4040
4134
|
}
|
|
4041
4135
|
}
|
|
4042
4136
|
}
|
|
4043
4137
|
}
|
|
4044
|
-
if (
|
|
4138
|
+
if (insAuthors.size > 0 || commentAuthors.size > 0) {
|
|
4139
|
+
const fullyWithinForeignIns = insAuthors.size > 0 && !hasNonForeignRealText && commentAuthors.size === 0;
|
|
4140
|
+
if ((match_mode === "strict" || match_mode === "first") && fullyWithinForeignIns) {
|
|
4141
|
+
continue;
|
|
4142
|
+
}
|
|
4143
|
+
const nestedAuthors = /* @__PURE__ */ new Set([
|
|
4144
|
+
...insAuthors,
|
|
4145
|
+
...commentAuthors
|
|
4146
|
+
]);
|
|
4045
4147
|
errors.push(
|
|
4046
4148
|
`- Edit ${i + 1 + index_offset} Failed: Modification targets an active insertion from another author (${Array.from(nestedAuthors).join(", ")}). Accept that change first or scope your edit outside of it.`
|
|
4047
4149
|
);
|
|
@@ -4135,59 +4237,6 @@ var RedlineEngine = class {
|
|
|
4135
4237
|
const edits = changes.filter(
|
|
4136
4238
|
(c) => c === null || typeof c !== "object" || !["accept", "reject", "reply"].includes(c.type)
|
|
4137
4239
|
);
|
|
4138
|
-
let mapper_dirty = false;
|
|
4139
|
-
for (const edit of edits) {
|
|
4140
|
-
if (typeof edit !== "object" || edit === null || !edit.target_text) continue;
|
|
4141
|
-
const is_regex = edit.regex || false;
|
|
4142
|
-
let matches = this.mapper.find_all_match_indices(edit.target_text, is_regex);
|
|
4143
|
-
let target_mapper = this.mapper;
|
|
4144
|
-
if (matches.length === 0) {
|
|
4145
|
-
if (!this.clean_mapper) {
|
|
4146
|
-
this.clean_mapper = new DocumentMapper(this.doc, true);
|
|
4147
|
-
}
|
|
4148
|
-
matches = this.clean_mapper.find_all_match_indices(edit.target_text, is_regex);
|
|
4149
|
-
target_mapper = this.clean_mapper;
|
|
4150
|
-
}
|
|
4151
|
-
for (const [start, length] of matches) {
|
|
4152
|
-
const spans = target_mapper.spans.filter(
|
|
4153
|
-
(s) => s.end > start && s.start < start + length
|
|
4154
|
-
);
|
|
4155
|
-
for (const s of spans) {
|
|
4156
|
-
if (s.ins_id) {
|
|
4157
|
-
const insNodes = findAllDescendants(this.doc.element, "w:ins").filter(
|
|
4158
|
-
(n) => n.getAttribute("w:id") === s.ins_id
|
|
4159
|
-
);
|
|
4160
|
-
if (insNodes.length > 0) {
|
|
4161
|
-
const auth = insNodes[0].getAttribute("w:author");
|
|
4162
|
-
if (auth && auth !== this.author) {
|
|
4163
|
-
const is_fully_contained_in_ins = start >= s.start && start + length <= s.end;
|
|
4164
|
-
const match_mode = edit.match_mode || "strict";
|
|
4165
|
-
if (!is_fully_contained_in_ins && match_mode !== "all") {
|
|
4166
|
-
const node = insNodes[0];
|
|
4167
|
-
this._clean_wrapping_comments(node);
|
|
4168
|
-
const parent = node.parentNode;
|
|
4169
|
-
if (parent) {
|
|
4170
|
-
if (parent.tagName === "w:trPr") {
|
|
4171
|
-
parent.removeChild(node);
|
|
4172
|
-
} else {
|
|
4173
|
-
while (node.firstChild) {
|
|
4174
|
-
parent.insertBefore(node.firstChild, node);
|
|
4175
|
-
}
|
|
4176
|
-
parent.removeChild(node);
|
|
4177
|
-
}
|
|
4178
|
-
}
|
|
4179
|
-
mapper_dirty = true;
|
|
4180
|
-
}
|
|
4181
|
-
}
|
|
4182
|
-
}
|
|
4183
|
-
}
|
|
4184
|
-
}
|
|
4185
|
-
}
|
|
4186
|
-
}
|
|
4187
|
-
if (mapper_dirty) {
|
|
4188
|
-
this.mapper = new DocumentMapper(this.doc);
|
|
4189
|
-
this.clean_mapper = null;
|
|
4190
|
-
}
|
|
4191
4240
|
if (!dry_run_mode) {
|
|
4192
4241
|
const action_errors = actions.length > 0 ? this.validate_review_actions(actions) : [];
|
|
4193
4242
|
const validate_edits_now = edits.length > 0 && action_errors.length > 0;
|
|
@@ -4431,6 +4480,7 @@ var RedlineEngine = class {
|
|
|
4431
4480
|
(a, b) => (b[0]._resolved_start_idx || 0) - (a[0]._resolved_start_idx || 0)
|
|
4432
4481
|
);
|
|
4433
4482
|
const occupied_ranges = [];
|
|
4483
|
+
const counted_split_groups = /* @__PURE__ */ new Set();
|
|
4434
4484
|
for (const [edit, orig_new] of resolved_edits) {
|
|
4435
4485
|
const start = edit._resolved_start_idx || 0;
|
|
4436
4486
|
const end = start + (edit.target_text ? edit.target_text.length : 0);
|
|
@@ -4459,13 +4509,20 @@ var RedlineEngine = class {
|
|
|
4459
4509
|
success = this._apply_table_edit(edit, false);
|
|
4460
4510
|
}
|
|
4461
4511
|
if (success) {
|
|
4462
|
-
|
|
4512
|
+
const group_id = edit._split_group_id;
|
|
4513
|
+
const first_in_group = group_id === void 0 || group_id === null || !counted_split_groups.has(group_id);
|
|
4514
|
+
if (first_in_group && group_id !== void 0 && group_id !== null) {
|
|
4515
|
+
counted_split_groups.add(group_id);
|
|
4516
|
+
}
|
|
4517
|
+
if (first_in_group) applied++;
|
|
4463
4518
|
occupied_ranges.push([start, end]);
|
|
4464
4519
|
edit._applied_status = true;
|
|
4465
4520
|
const parent = edit._parent_edit_ref;
|
|
4466
4521
|
if (parent) {
|
|
4467
4522
|
parent._applied_status = true;
|
|
4468
|
-
|
|
4523
|
+
if (first_in_group) {
|
|
4524
|
+
parent._occurrences_modified = (parent._occurrences_modified || 0) + 1;
|
|
4525
|
+
}
|
|
4469
4526
|
const [path, page] = this._get_heading_path_and_page(
|
|
4470
4527
|
start,
|
|
4471
4528
|
this.mapper.full_text,
|
|
@@ -4476,7 +4533,9 @@ var RedlineEngine = class {
|
|
|
4476
4533
|
parent._pages = pages;
|
|
4477
4534
|
parent._heading_path = path;
|
|
4478
4535
|
} else {
|
|
4479
|
-
|
|
4536
|
+
if (first_in_group) {
|
|
4537
|
+
edit._occurrences_modified = (edit._occurrences_modified || 0) + 1;
|
|
4538
|
+
}
|
|
4480
4539
|
const [path, page] = this._get_heading_path_and_page(
|
|
4481
4540
|
start,
|
|
4482
4541
|
this.mapper.full_text,
|
|
@@ -4773,6 +4832,51 @@ var RedlineEngine = class {
|
|
|
4773
4832
|
final_target = actual_doc_text.substring(prefix_len, t_end);
|
|
4774
4833
|
final_new = current_effective_new_text.substring(prefix_len, n_end);
|
|
4775
4834
|
effective_start_idx = start_idx + prefix_len;
|
|
4835
|
+
const target_segs = actual_doc_text.split("\n\n");
|
|
4836
|
+
const new_segs = current_effective_new_text.split("\n\n");
|
|
4837
|
+
if (actual_doc_text.includes("\n\n") && target_segs.length === new_segs.length) {
|
|
4838
|
+
const split_sub_edits = [];
|
|
4839
|
+
let seg_offset = start_idx;
|
|
4840
|
+
let comment_assigned = false;
|
|
4841
|
+
for (let k = 0; k < target_segs.length; k++) {
|
|
4842
|
+
const t_seg = target_segs[k];
|
|
4843
|
+
const n_seg = new_segs[k];
|
|
4844
|
+
if (t_seg !== n_seg) {
|
|
4845
|
+
const [seg_prefix, seg_suffix] = trim_common_context(t_seg, n_seg);
|
|
4846
|
+
const seg_target = t_seg.substring(
|
|
4847
|
+
seg_prefix,
|
|
4848
|
+
t_seg.length - seg_suffix
|
|
4849
|
+
);
|
|
4850
|
+
const seg_new = n_seg.substring(
|
|
4851
|
+
seg_prefix,
|
|
4852
|
+
n_seg.length - seg_suffix
|
|
4853
|
+
);
|
|
4854
|
+
const seg_start = seg_offset + seg_prefix;
|
|
4855
|
+
let seg_op;
|
|
4856
|
+
if (!seg_target && seg_new) seg_op = "INSERTION";
|
|
4857
|
+
else if (seg_target && !seg_new) seg_op = "DELETION";
|
|
4858
|
+
else if (seg_target && seg_new) seg_op = "MODIFICATION";
|
|
4859
|
+
else seg_op = "COMMENT_ONLY";
|
|
4860
|
+
const seg_comment = edit.comment && !comment_assigned ? edit.comment : null;
|
|
4861
|
+
if (seg_comment) comment_assigned = true;
|
|
4862
|
+
split_sub_edits.push({
|
|
4863
|
+
type: "modify",
|
|
4864
|
+
target_text: seg_target,
|
|
4865
|
+
new_text: seg_new,
|
|
4866
|
+
comment: seg_comment,
|
|
4867
|
+
_match_start_index: seg_start,
|
|
4868
|
+
_internal_op: seg_op,
|
|
4869
|
+
_active_mapper_ref: active_mapper,
|
|
4870
|
+
_split_group_id: start_idx
|
|
4871
|
+
});
|
|
4872
|
+
}
|
|
4873
|
+
seg_offset += t_seg.length + 2;
|
|
4874
|
+
}
|
|
4875
|
+
if (split_sub_edits.length > 0) {
|
|
4876
|
+
for (const sub of split_sub_edits) all_sub_edits.push(sub);
|
|
4877
|
+
continue;
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4776
4880
|
if (!final_target && final_new) effective_op = "INSERTION";
|
|
4777
4881
|
else if (final_target && !final_new) effective_op = "DELETION";
|
|
4778
4882
|
else if (final_target && final_new) effective_op = "MODIFICATION";
|
|
@@ -4792,6 +4896,35 @@ var RedlineEngine = class {
|
|
|
4792
4896
|
if (match_mode === "all" || all_sub_edits.length > 1) return all_sub_edits;
|
|
4793
4897
|
return all_sub_edits[0];
|
|
4794
4898
|
}
|
|
4899
|
+
/**
|
|
4900
|
+
* Split a <w:ins> so that everything up to and INCLUDING split_after stays in
|
|
4901
|
+
* a left <w:ins>, new_elem is placed between, and the remainder moves to a
|
|
4902
|
+
* right <w:ins> — all at the grandparent level. Used when revising another
|
|
4903
|
+
* author's pending insertion: the <w:del> stays nested in their <w:ins> while
|
|
4904
|
+
* our replacement <w:ins> lands as a sibling, so we never nest <w:ins> in
|
|
4905
|
+
* <w:ins>.
|
|
4906
|
+
*/
|
|
4907
|
+
_insert_and_split_ins(parent_ins, split_after, new_elem) {
|
|
4908
|
+
const grandparent = parent_ins.parentNode;
|
|
4909
|
+
if (!grandparent) return;
|
|
4910
|
+
const left = parent_ins.cloneNode(false);
|
|
4911
|
+
const right = parent_ins.cloneNode(false);
|
|
4912
|
+
let toRight = false;
|
|
4913
|
+
for (const kid of Array.from(parent_ins.childNodes)) {
|
|
4914
|
+
parent_ins.removeChild(kid);
|
|
4915
|
+
if (!toRight) {
|
|
4916
|
+
left.appendChild(kid);
|
|
4917
|
+
if (kid === split_after) toRight = true;
|
|
4918
|
+
} else {
|
|
4919
|
+
right.appendChild(kid);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
if (left.childNodes.length > 0) grandparent.insertBefore(left, parent_ins);
|
|
4923
|
+
grandparent.insertBefore(new_elem, parent_ins);
|
|
4924
|
+
if (right.childNodes.length > 0)
|
|
4925
|
+
grandparent.insertBefore(right, parent_ins);
|
|
4926
|
+
grandparent.removeChild(parent_ins);
|
|
4927
|
+
}
|
|
4795
4928
|
_apply_single_edit_indexed(edit, orig_new, rebuild_map) {
|
|
4796
4929
|
let op = edit._internal_op;
|
|
4797
4930
|
const active_mapper = edit._active_mapper_ref || this.mapper;
|
|
@@ -4999,7 +5132,16 @@ var RedlineEngine = class {
|
|
|
4999
5132
|
const is_inline_first = result.first_node.tagName === "w:ins";
|
|
5000
5133
|
if (is_inline_first) {
|
|
5001
5134
|
if (anchor_run) {
|
|
5002
|
-
|
|
5135
|
+
const anchor_parent = anchor_run._element.parentNode;
|
|
5136
|
+
if (anchor_parent && anchor_parent.tagName === "w:ins") {
|
|
5137
|
+
this._insert_and_split_ins(
|
|
5138
|
+
anchor_parent,
|
|
5139
|
+
anchor_run._element,
|
|
5140
|
+
result.first_node
|
|
5141
|
+
);
|
|
5142
|
+
} else {
|
|
5143
|
+
insertAfter(result.first_node, anchor_run._element);
|
|
5144
|
+
}
|
|
5003
5145
|
} else if (anchor_para) {
|
|
5004
5146
|
anchor_para._element.appendChild(result.first_node);
|
|
5005
5147
|
}
|
|
@@ -5109,7 +5251,12 @@ var RedlineEngine = class {
|
|
|
5109
5251
|
if (result.first_node) {
|
|
5110
5252
|
const is_inline_first = result.first_node.tagName === "w:ins";
|
|
5111
5253
|
if (is_inline_first) {
|
|
5112
|
-
|
|
5254
|
+
const del_parent = last_del.parentNode;
|
|
5255
|
+
if (del_parent && del_parent.tagName === "w:ins") {
|
|
5256
|
+
this._insert_and_split_ins(del_parent, last_del, result.first_node);
|
|
5257
|
+
} else {
|
|
5258
|
+
insertAfter(result.first_node, last_del);
|
|
5259
|
+
}
|
|
5113
5260
|
ins_elem = result.first_node;
|
|
5114
5261
|
} else {
|
|
5115
5262
|
ins_elem = result.last_ins;
|