@adeu/core 1.7.5 → 1.9.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 +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/docx/dom.ts +4 -0
- package/src/engine.bugs.test.ts +25 -10
package/package.json
CHANGED
package/src/docx/dom.ts
CHANGED
|
@@ -49,6 +49,10 @@ export function findAllDescendants(
|
|
|
49
49
|
* Parses raw XML strings into xmldom Documents.
|
|
50
50
|
*/
|
|
51
51
|
export function parseXml(xmlString: string): Document {
|
|
52
|
+
// Strip UTF-8 BOM if present
|
|
53
|
+
if (xmlString.startsWith("\uFEFF")) {
|
|
54
|
+
xmlString = xmlString.slice(1);
|
|
55
|
+
}
|
|
52
56
|
return new DOMParser().parseFromString(xmlString, "text/xml");
|
|
53
57
|
}
|
|
54
58
|
|
package/src/engine.bugs.test.ts
CHANGED
|
@@ -134,6 +134,12 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
134
134
|
// Direct string equality so Vitest prints the exact diff if they mismatch!
|
|
135
135
|
expect(serialized).toBe(expected);
|
|
136
136
|
});
|
|
137
|
+
|
|
138
|
+
it("BUG-BOM-1: parseXml successfully strips leading UTF-8 BOM (\\uFEFF)", () => {
|
|
139
|
+
const rawXml = `\uFEFF<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"></w:document>`;
|
|
140
|
+
const docXml = parseXml(rawXml);
|
|
141
|
+
expect(docXml.documentElement.tagName).toBe("w:document");
|
|
142
|
+
});
|
|
137
143
|
it("BUG-11b: Sweeps orphaned comment anchors when accepting tracked changes", async () => {
|
|
138
144
|
const doc = await createTestDocument();
|
|
139
145
|
addParagraph(doc, "Confidential Information");
|
|
@@ -235,7 +241,7 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
235
241
|
"",
|
|
236
242
|
null,
|
|
237
243
|
"123",
|
|
238
|
-
doc.element.ownerDocument
|
|
244
|
+
doc.element.ownerDocument!,
|
|
239
245
|
);
|
|
240
246
|
expect(ins).toBeNull();
|
|
241
247
|
});
|
|
@@ -245,7 +251,7 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
245
251
|
const p = addParagraph(doc, "Short heading");
|
|
246
252
|
|
|
247
253
|
const fakeCache = {
|
|
248
|
-
|
|
254
|
+
CustomHeading: { name: "Custom Heading", outline_level: 2, bold: true },
|
|
249
255
|
};
|
|
250
256
|
(doc.pkg as any)._adeu_style_cache = [fakeCache, "Normal"];
|
|
251
257
|
|
|
@@ -259,7 +265,7 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
259
265
|
const buf = await doc.save();
|
|
260
266
|
const body = await extractTextFromBuffer(buf, false);
|
|
261
267
|
const pages = paginate(body, "");
|
|
262
|
-
|
|
268
|
+
|
|
263
269
|
const outlineNodes = extract_outline(
|
|
264
270
|
doc,
|
|
265
271
|
body,
|
|
@@ -295,7 +301,7 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
295
301
|
const end = xmlDoc.createElement("w:commentRangeEnd");
|
|
296
302
|
end.setAttribute("w:id", c_id);
|
|
297
303
|
p.appendChild(end);
|
|
298
|
-
|
|
304
|
+
|
|
299
305
|
const ref_run = xmlDoc.createElement("w:r");
|
|
300
306
|
const ref = xmlDoc.createElement("w:commentReference");
|
|
301
307
|
ref.setAttribute("w:id", c_id);
|
|
@@ -428,10 +434,18 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
428
434
|
|
|
429
435
|
// Author B tries to modify Author A's pending insertion
|
|
430
436
|
const engineB = new RedlineEngine(doc, "Author B");
|
|
431
|
-
|
|
437
|
+
|
|
432
438
|
expect(() => {
|
|
433
|
-
engineB.process_batch([
|
|
434
|
-
|
|
439
|
+
engineB.process_batch([
|
|
440
|
+
{
|
|
441
|
+
type: "modify",
|
|
442
|
+
target_text: "Inserted by A.",
|
|
443
|
+
new_text: "Modified by B.",
|
|
444
|
+
},
|
|
445
|
+
]);
|
|
446
|
+
}).toThrowError(
|
|
447
|
+
/Accept that change first or scope your edit outside of it/,
|
|
448
|
+
);
|
|
435
449
|
});
|
|
436
450
|
|
|
437
451
|
it("BUG-CROSS-PARA-1: Cross-paragraph modify coalesces paragraphs and tracks para-mark deletion", async () => {
|
|
@@ -452,7 +466,7 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
452
466
|
|
|
453
467
|
const buf = await doc.save();
|
|
454
468
|
const cleanText = await extractTextFromBuffer(buf, true);
|
|
455
|
-
|
|
469
|
+
|
|
456
470
|
expect(cleanText).not.toContain("ends here.\n\n");
|
|
457
471
|
expect(cleanText).toContain("Clause 1 ends here. MERGED here.");
|
|
458
472
|
});
|
|
@@ -467,14 +481,15 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
467
481
|
engine.process_batch([
|
|
468
482
|
{
|
|
469
483
|
type: "modify",
|
|
470
|
-
target_text:
|
|
484
|
+
target_text:
|
|
485
|
+
"ends here.\n\nParagraph 2 is in the middle.\n\nParagraph 3 begins",
|
|
471
486
|
new_text: "ends here. MERGED",
|
|
472
487
|
},
|
|
473
488
|
]);
|
|
474
489
|
|
|
475
490
|
engine.accept_all_revisions();
|
|
476
491
|
const cleanText = await extractTextFromBuffer(await doc.save(), true);
|
|
477
|
-
|
|
492
|
+
|
|
478
493
|
expect(cleanText).not.toContain("Paragraph 2");
|
|
479
494
|
expect(cleanText).toContain("Paragraph 1 ends here. MERGED here.");
|
|
480
495
|
});
|