[Bug]: HTML output of Table is missing colgroup element (#4281)

* [Bug]: HTML output of Table is missing colgroup element
Fixes #4280

* Fixed typo and added some documentation
This commit is contained in:
Timo Santi 2023-10-10 05:22:58 +03:00 committed by GitHub
parent 6d8577eebf
commit 6b2edc5d82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 6 deletions

View File

@ -63,7 +63,7 @@ context('/src/Nodes/Table/React/', () => {
const html = editor.getHTML() const html = editor.getHTML()
expect(html).to.equal( expect(html).to.equal(
'<table><tbody><tr><td colspan="1" rowspan="1"><p></p></td></tr></tbody></table>', '<table style="minWidth: 25px"><colgroup><col></colgroup><tbody><tr><td colspan="1" rowspan="1"><p></p></td></tr></tbody></table>',
) )
}) })
}) })
@ -75,7 +75,7 @@ context('/src/Nodes/Table/React/', () => {
const html = editor.getHTML() const html = editor.getHTML()
expect(html).to.equal( expect(html).to.equal(
'<table><tbody><tr><th colspan="1" rowspan="1"><p></p></th></tr></tbody></table>', '<table style="minWidth: 25px"><colgroup><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p></p></th></tr></tbody></table>',
) )
}) })
}) })

View File

@ -62,7 +62,7 @@ context('/src/Nodes/Table/Vue/', () => {
const html = editor.getHTML() const html = editor.getHTML()
expect(html).to.equal('<table><tbody><tr><td colspan="1" rowspan="1"><p></p></td></tr></tbody></table>') expect(html).to.equal('<table style="minWidth: 25px"><colgroup><col></colgroup><tbody><tr><td colspan="1" rowspan="1"><p></p></td></tr></tbody></table>')
}) })
}) })
@ -72,7 +72,7 @@ context('/src/Nodes/Table/Vue/', () => {
const html = editor.getHTML() const html = editor.getHTML()
expect(html).to.equal('<table><tbody><tr><th colspan="1" rowspan="1"><p></p></th></tr></tbody></table>') expect(html).to.equal('<table style="minWidth: 25px"><colgroup><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p></p></th></tr></tbody></table>')
}) })
}) })

View File

@ -22,8 +22,10 @@ import {
toggleHeaderCell, toggleHeaderCell,
} from '@tiptap/pm/tables' } from '@tiptap/pm/tables'
import { NodeView } from '@tiptap/pm/view' import { NodeView } from '@tiptap/pm/view'
import { DOMOutputSpec } from 'prosemirror-model'
import { TableView } from './TableView.js' import { TableView } from './TableView.js'
import { createColGroup } from './utilities/createColGroup.js'
import { createTable } from './utilities/createTable.js' import { createTable } from './utilities/createTable.js'
import { deleteTableWhenAllCellsSelected } from './utilities/deleteTableWhenAllCellsSelected.js' import { deleteTableWhenAllCellsSelected } from './utilities/deleteTableWhenAllCellsSelected.js'
@ -110,8 +112,24 @@ export const Table = Node.create<TableOptions>({
return [{ tag: 'table' }] return [{ tag: 'table' }]
}, },
renderHTML({ HTMLAttributes }) { renderHTML({ node, HTMLAttributes }) {
return ['table', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), ['tbody', 0]] const { colgroup, tableWidth, tableMinWidth } = createColGroup(
node,
this.options.cellMinWidth,
)
const table: DOMOutputSpec = [
'table',
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
style: tableWidth
? `width: ${tableWidth}`
: `minWidth: ${tableMinWidth}`,
}),
colgroup,
['tbody', 0],
]
return table
}, },
addCommands() { addCommands() {

View File

@ -0,0 +1,51 @@
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
import { DOMOutputSpec } from 'prosemirror-model'
/**
* Creates a colgroup element for a table node in ProseMirror.
*
* @param node - The ProseMirror node representing the table.
* @param cellMinWidth - The minimum width of a cell in the table.
* @param overrideCol - (Optional) The index of the column to override the width of.
* @param overrideValue - (Optional) The width value to use for the overridden column.
* @returns An object containing the colgroup element, the total width of the table, and the minimum width of the table.
*/
export function createColGroup(
node: ProseMirrorNode,
cellMinWidth: number,
overrideCol?: number,
overrideValue?: any,
) {
let totalWidth = 0
let fixedWidth = true
const cols: DOMOutputSpec[] = []
const row = node.firstChild
if (!row) {
return {}
}
for (let i = 0, col = 0; i < row.childCount; i += 1) {
const { colspan, colwidth } = row.child(i).attrs
for (let j = 0; j < colspan; j += 1, col += 1) {
const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j]
const cssWidth = hasWidth ? `${hasWidth}px` : ''
totalWidth += hasWidth || cellMinWidth
if (!hasWidth) {
fixedWidth = false
}
cols.push(['col', cssWidth ? { style: `width: ${cssWidth}` } : {}])
}
}
const tableWidth = fixedWidth ? `${totalWidth}px` : ''
const tableMinWidth = fixedWidth ? '' : `${totalWidth}px`
const colgroup: DOMOutputSpec = ['colgroup', {}, ...cols]
return { colgroup, tableWidth, tableMinWidth }
}