mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #25469 from overleaf/mj-paste-tables-multicol
[web] Improve borders and column definitions of pasted tables with multi-column cells GitOrigin-RevId: fe9c44bd8ac6a34e8a8057f1a07d97771a116e1a
This commit is contained in:
@@ -487,6 +487,7 @@ const tabular = (element: HTMLTableElement) => {
|
||||
alignment: string
|
||||
borderLeft: boolean
|
||||
borderRight: boolean
|
||||
inferred?: boolean
|
||||
}> = []
|
||||
|
||||
const rows = element.querySelectorAll('tr')
|
||||
@@ -500,16 +501,29 @@ const tabular = (element: HTMLTableElement) => {
|
||||
|
||||
for (const cell of cells) {
|
||||
// NOTE: reading the alignment and borders from the first cell definition in each column
|
||||
if (definitions[index] === undefined) {
|
||||
const { textAlign, borderLeftStyle, borderRightStyle } = cell.style
|
||||
const colspan = Number(cell.getAttribute('colspan') ?? 1)
|
||||
const { textAlign, borderLeftStyle, borderRightStyle } = cell.style
|
||||
|
||||
definitions[index] = {
|
||||
alignment: textAlign,
|
||||
borderLeft: visibleBorderStyle(borderLeftStyle),
|
||||
borderRight: visibleBorderStyle(borderRightStyle),
|
||||
for (let i = 0; i < colspan; i++) {
|
||||
if (
|
||||
// There's no definition for this column
|
||||
definitions[index + i] === undefined ||
|
||||
// There's an inferred definition of the column, and we're a cell that
|
||||
// can accurately represent the whole column, since we're not a
|
||||
// multicolumn cell ourselves.
|
||||
(colspan === 1 && definitions[index + i].inferred)
|
||||
) {
|
||||
definitions[index + i] = {
|
||||
alignment: textAlign,
|
||||
borderLeft: visibleBorderStyle(borderLeftStyle),
|
||||
borderRight: visibleBorderStyle(borderRightStyle),
|
||||
// We can't trust the details from a multicolumn cell to represent the
|
||||
// whole column, so we mark it as inferred.
|
||||
inferred: colspan > 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
index += Number(cell.getAttribute('colspan') ?? 1)
|
||||
index += colspan
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,9 +628,12 @@ const nextRowHasBorderStyle = (
|
||||
}
|
||||
|
||||
const startMulticolumn = (element: HTMLTableCellElement): string => {
|
||||
const { textAlign, borderLeftStyle, borderRightStyle } = element.style
|
||||
const colspan = Number(element.getAttribute('colspan') || 1)
|
||||
const alignment = cellAlignment.get(element.style.textAlign) ?? 'l'
|
||||
return `\\multicolumn{${colspan}}{${alignment}}{`
|
||||
const alignment = cellAlignment.get(textAlign) ?? 'l'
|
||||
const borderLeft = visibleBorderStyle(borderLeftStyle)
|
||||
const borderRight = visibleBorderStyle(borderRightStyle)
|
||||
return `\\multicolumn{${colspan}}{${borderLeft ? '|' : ''}${alignment}${borderRight ? '|' : ''}}{`
|
||||
}
|
||||
|
||||
const startMultirow = (element: HTMLTableCellElement): string => {
|
||||
|
||||
@@ -227,6 +227,40 @@ describe('<CodeMirrorEditor/> paste HTML in Visual mode', function () {
|
||||
cy.get('.table-generator-cell[colspan="2"]').should('have.length', 2)
|
||||
})
|
||||
|
||||
it('handles a pasted 1-row table with merged columns', function () {
|
||||
mountEditor()
|
||||
|
||||
const data = [
|
||||
`<table><tbody>`,
|
||||
`<tr><td>test</td><td colspan="2">test</td></tr>`,
|
||||
`</tbody></table>`,
|
||||
].join('')
|
||||
|
||||
const clipboardData = new DataTransfer()
|
||||
clipboardData.setData('text/html', data)
|
||||
cy.get('@content').trigger('paste', { clipboardData })
|
||||
|
||||
cy.get('@content').should('have.text', 'testtest' + menuIconsText)
|
||||
cy.get('.table-generator-cell').should('have.length', 2)
|
||||
cy.get('.table-generator-cell[colspan="2"]').should('have.length', 1)
|
||||
})
|
||||
|
||||
it('handles a pasted table with a bordered merged column', function () {
|
||||
mountEditor()
|
||||
|
||||
const data = [
|
||||
`<table><tbody>`,
|
||||
`<tr><td style="border-right:1px solid black;border-left:1px solid black;">test</td></tr>`,
|
||||
`</tbody></table>`,
|
||||
].join('')
|
||||
|
||||
const clipboardData = new DataTransfer()
|
||||
clipboardData.setData('text/html', data)
|
||||
cy.get('@content').trigger('paste', { clipboardData })
|
||||
cy.get('.table-generator-cell-border-right').should('have.length', 1)
|
||||
cy.get('.table-generator-cell-border-left').should('have.length', 1)
|
||||
})
|
||||
|
||||
it('handles a pasted table with merged rows', function () {
|
||||
mountEditor()
|
||||
|
||||
@@ -312,8 +346,8 @@ describe('<CodeMirrorEditor/> paste HTML in Visual mode', function () {
|
||||
cy.get('@content').should('have.text', 'foofoobarfoobar' + menuIconsText)
|
||||
cy.get('.table-generator-cell').should('have.length', 5)
|
||||
cy.get('.table-generator-cell[colspan="2"]').should('have.length', 1)
|
||||
cy.get('.table-generator-cell-border-left').should('have.length', 2)
|
||||
cy.get('.table-generator-cell-border-right').should('have.length', 4)
|
||||
cy.get('.table-generator-cell-border-left').should('have.length', 3)
|
||||
cy.get('.table-generator-cell-border-right').should('have.length', 5)
|
||||
cy.get('.table-generator-row-border-top').should('have.length', 5)
|
||||
cy.get('.table-generator-row-border-bottom').should('have.length', 2)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user