fix: a styled table writes no table-level borders
Every cell already writes all four sides itself, and on a styled table the table-level black default showed in Word, which lets table borders beat a cell's "none" (only "nil" loses) — LibreOffice lets the cell win, so only Word drew the grid over the style. Plain tables keep the default grid via the per-cell fallback.
This commit is contained in:
1 parent
1e88427154
commit
3f047efca8
2 files changed
+15
-5
No files matched your search
+11
-5
@@ -2039,11 +2039,13 @@ function cellForce(style: TableStyle | undefined, cell: TiptapNode, bg: unknown)
|
||||
return force;
|
||||
}
|
||||
|
||||
function docxCellBorder(attrs: Record<string, unknown> | undefined, side: BorderSide): IBorderOptions {
|
||||
const noneBorder: IBorderOptions = { style: BorderStyle.NONE, size: 0, color: 'auto' };
|
||||
|
||||
function docxCellBorder(attrs: Record<string, unknown> | undefined, side: BorderSide, fallback: IBorderOptions = cellBorder): IBorderOptions {
|
||||
const b = parseBorderAttr(attrs?.[side] as string | null);
|
||||
if (b === 'none') return { style: BorderStyle.NONE, size: 0, color: 'auto' };
|
||||
if (b === 'none') return noneBorder;
|
||||
if (b) return { style: BorderStyle.SINGLE, size: Math.max(2, Math.round(b.widthPt * 8)), color: hexColor(b.color) ?? '000000' };
|
||||
return cellBorder;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
// A synthetic inline node standing for the whole content of a formula cell; the
|
||||
@@ -2097,6 +2099,10 @@ function tableToDocx(node: TiptapNode, contentWidthCm: number, num: Numbering):
|
||||
|
||||
// w:tblHeader on the first row is what makes Word repeat it on every page.
|
||||
const repeatHeader = node.attrs?.repeatHeader === true;
|
||||
// Every cell writes all four sides itself, so the table level adds nothing — and on a
|
||||
// styled table its black default shows in Word, whose table borders beat a cell's
|
||||
// "none" (only "nil" loses). The editor's base grid still arrives via the cell fallback.
|
||||
const tableBorder = tableStyle ? noneBorder : cellBorder;
|
||||
const tableRows = rows.map((row, rowIndex) => {
|
||||
const rh = row.attrs?.rowHeight;
|
||||
let col = 0;
|
||||
@@ -2158,8 +2164,8 @@ function tableToDocx(node: TiptapNode, contentWidthCm: number, num: Numbering):
|
||||
layout: TableLayoutType.FIXED,
|
||||
margins: { marginUnitType: WidthType.DXA, top: cmToTwip(pad[0]), right: cmToTwip(pad[1]), bottom: cmToTwip(pad[2]), left: cmToTwip(pad[3]) },
|
||||
borders: {
|
||||
top: cellBorder, bottom: cellBorder, left: cellBorder, right: cellBorder,
|
||||
insideHorizontal: cellBorder, insideVertical: cellBorder,
|
||||
top: tableBorder, bottom: tableBorder, left: tableBorder, right: tableBorder,
|
||||
insideHorizontal: tableBorder, insideVertical: tableBorder,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -153,6 +153,10 @@ describe('DOCX export → import round trip', () => {
|
||||
expect(stylesXml, 'the imported style is a direct w:styles child').not.toContain('<undefined');
|
||||
// The header region's white bold is presentational in the editor, baked here.
|
||||
expect(xml).toContain('<w:color w:val="FFFFFF"');
|
||||
// The style paints every border via the cells; a black table-level default would
|
||||
// show in Word, whose table borders beat a cell's "none" (only "nil" loses).
|
||||
const tblPr = /<w:tblPr>[\s\S]*?<\/w:tblPr>/.exec(xml)![0];
|
||||
expect(tblPr).not.toContain('w:val="single"');
|
||||
|
||||
const res = importDocx(bytes).content as N;
|
||||
const table = walk(res, 'table')[0];
|
||||
|
||||
Reference in new issue
Block a user