Skip to content

Commit

Permalink
[Bug]: HTML output of Table is missing colgroup element (#4281)
Browse files Browse the repository at this point in the history
* [Bug]: HTML output of Table is missing colgroup element
Fixes #4280

* Fixed typo and added some documentation
  • Loading branch information
diginikkari authored Oct 10, 2023
1 parent 6d8577e commit 6b2edc5
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 6 deletions.
4 changes: 2 additions & 2 deletions demos/src/Nodes/Table/React/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ context('/src/Nodes/Table/React/', () => {
const html = editor.getHTML()

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>',
)
})
})
Expand All @@ -75,7 +75,7 @@ context('/src/Nodes/Table/React/', () => {
const html = editor.getHTML()

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>',
)
})
})
Expand Down
4 changes: 2 additions & 2 deletions demos/src/Nodes/Table/Vue/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ context('/src/Nodes/Table/Vue/', () => {

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>')
})
})

Expand All @@ -72,7 +72,7 @@ context('/src/Nodes/Table/Vue/', () => {

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>')
})
})

Expand Down
22 changes: 20 additions & 2 deletions packages/extension-table/src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import {
toggleHeaderCell,
} from '@tiptap/pm/tables'
import { NodeView } from '@tiptap/pm/view'
import { DOMOutputSpec } from 'prosemirror-model'

import { TableView } from './TableView.js'
import { createColGroup } from './utilities/createColGroup.js'
import { createTable } from './utilities/createTable.js'
import { deleteTableWhenAllCellsSelected } from './utilities/deleteTableWhenAllCellsSelected.js'

Expand Down Expand Up @@ -110,8 +112,24 @@ export const Table = Node.create<TableOptions>({
return [{ tag: 'table' }]
},

renderHTML({ HTMLAttributes }) {
return ['table', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), ['tbody', 0]]
renderHTML({ node, HTMLAttributes }) {
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() {
Expand Down
51 changes: 51 additions & 0 deletions packages/extension-table/src/utilities/createColGroup.ts
Original file line number Diff line number Diff line change
@@ -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 }
}

0 comments on commit 6b2edc5

Please sign in to comment.