[visual] Improve pasting of a table containing a caption (#14322)

GitOrigin-RevId: 6d7676a9412c5614f85c17e16509c80ad937cc40
This commit is contained in:
Alf Eaton 2023-08-15 15:23:35 +01:00 committed by Copybot
parent a8d7306fc4
commit a55bb9c4b2
2 changed files with 50 additions and 8 deletions

View file

@ -30,7 +30,9 @@ export const pasteHtml = Prec.highest(
)
return true
} catch {
} catch (error) {
console.error(error)
// fall back to the default paste handler
return false
}
@ -54,6 +56,9 @@ const htmlToLaTeX = (html: string) => {
// remove style elements
removeUnwantedElements(documentElement, 'style')
// pre-process table elements
processTables(documentElement)
// protect special characters in non-LaTeX text nodes
protectSpecialCharacters(documentElement)
@ -147,6 +152,24 @@ const matchingParents = (element: HTMLElement, selector: string) => {
return matches
}
const processTables = (element: HTMLElement) => {
for (const table of element.querySelectorAll('table')) {
// create a wrapper element for the table and the caption
const container = document.createElement('div')
container.className = 'ol-table-wrap'
table.after(container)
// move the caption (if it exists) into the container before the table
const caption = table.querySelector('caption')
if (caption) {
container.append(caption)
}
// move the table into the container
container.append(table)
}
}
const tabular = (element: HTMLTableElement) => {
const options = []
@ -335,13 +358,15 @@ export const selectors = [
start: () => `\n\n\\begin{verbatim}\n`,
end: () => `\n\\end{verbatim}\n\n`,
}),
createSelector({
selector: '.ol-table-wrap',
start: element => `\n\n\\begin{table}\n\\centering\n`,
end: () => `\n\\end{table}\n\n`,
}),
createSelector({
selector: 'table',
start: element =>
`\n\n\\begin{table}\n\\centering\n\\begin{tabular}{${tabular(
element
)}}\n`,
end: () => `\n\\end{tabular}\n\\end{table}\n\n`,
start: element => `\n\\begin{tabular}{${tabular(element)}}\n`,
end: () => `\n\\end{tabular}\n`,
}),
createSelector({
selector: 'thead',
@ -386,8 +411,8 @@ export const selectors = [
},
}),
createSelector({
selector: 'table > caption',
start: () => `\n\n\\caption{\\label{tab:example}`,
selector: 'caption',
start: () => `\n\n\\caption{`,
end: () => `}\n\n`,
}),
createSelector({

View file

@ -132,6 +132,23 @@ describe('<CodeMirrorEditor/> paste HTML in Visual mode', function () {
)
})
it('handles a pasted table with a caption', function () {
mountEditor()
const data =
'<table><caption>A table</caption><tbody><tr><td>foo</td><td>bar</td></tr></tbody></table>'
const clipboardData = new DataTransfer()
clipboardData.setData('text/html', data)
cy.spy(clipboardData, 'getData').as('get-data')
cy.get('@content').trigger('paste', { clipboardData })
cy.get('@content').should(
'have.text',
'A table\\begin{tabular}{c c}foo & bar ↩\\end{tabular}'
)
})
it('handles a pasted link', function () {
mountEditor()