Respect DOCX underline none on import
This commit is contained in:
+10
-1
@@ -1493,7 +1493,7 @@ function docxRunToHtml(run: unknown, imageDataByRelationshipId: DocxImageDataByR
|
||||
if (hasDocxBoolean(properties, "w:i")) {
|
||||
html = `<em>${html}</em>`;
|
||||
}
|
||||
if (hasDocxBoolean(properties, "w:u")) {
|
||||
if (hasDocxUnderline(properties)) {
|
||||
html = `<u>${html}</u>`;
|
||||
}
|
||||
if (hasStrike) {
|
||||
@@ -1707,6 +1707,15 @@ function hasDocxBoolean(properties: XmlRecord, key: string) {
|
||||
return !["0", "false", "off"].includes(value.toLowerCase());
|
||||
}
|
||||
|
||||
function hasDocxUnderline(properties: XmlRecord) {
|
||||
if (!Object.prototype.hasOwnProperty.call(properties, "w:u")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const value = (docxAttribute(childRecord(properties, "w:u"), "w:val") || docxAttribute(childRecord(properties, "w:u"), "val")).trim().toLowerCase();
|
||||
return !["0", "false", "off", "none"].includes(value);
|
||||
}
|
||||
|
||||
function childRecord(value: unknown, key: string): XmlRecord {
|
||||
const child = asRecord(value)[key];
|
||||
if (Array.isArray(child)) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import JSZip from "jszip";
|
||||
import { exportDocxBlob, htmlToWordBlocks, importDocxFile } from "./wordOffice";
|
||||
|
||||
const tinyPngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=";
|
||||
@@ -128,6 +129,36 @@ describe("wordOffice DOCX import", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not import DOCX underline when w:u val is none", async () => {
|
||||
const sourceBlob = await exportDocxBlob("UnderlineNone.docx", '<p><span style="color: #0f5fae;">Not underlined</span></p>');
|
||||
const zip = await JSZip.loadAsync(await sourceBlob.arrayBuffer());
|
||||
const documentXml = (await zip.file("word/document.xml")?.async("string")) ?? "";
|
||||
const patchedDocumentXml = documentXml.replace(/(<w:rPr\b[^>]*>[\s\S]*?)(<\/w:rPr>)/, '$1<w:u w:val="none"/>$2');
|
||||
expect(patchedDocumentXml).toContain('<w:u w:val="none"/>');
|
||||
zip.file("word/document.xml", patchedDocumentXml);
|
||||
const patchedBlob = await zip.generateAsync({
|
||||
type: "blob",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
});
|
||||
|
||||
const imported = await importDocxFile(
|
||||
new File([patchedBlob], "UnderlineNone.docx", {
|
||||
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
})
|
||||
);
|
||||
|
||||
expect(imported.html).not.toContain("<u>Not underlined</u>");
|
||||
expect(imported.html).not.toContain("<u>");
|
||||
expect(imported.html).toContain("color: #0F5FAE;");
|
||||
expect(htmlToWordBlocks(imported.html)).toEqual([
|
||||
{
|
||||
type: "paragraph",
|
||||
text: "Not underlined",
|
||||
runs: [{ text: "Not underlined", color: "0F5FAE" }]
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("imports DOCX subscript and superscript from OOXML", async () => {
|
||||
const blob = await exportDocxBlob("Indexes.docx", "<p>H<sub>2</sub>O m<sup>2</sup></p>");
|
||||
const file = new File([blob], "Indexes.docx", {
|
||||
|
||||
Reference in New Issue
Block a user