Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cells pasted from clipboard's tables won't contain unnecessary line breaks #10745

Merged
merged 7 commits into from
Jan 31, 2024
8 changes: 8 additions & 0 deletions .changelogs/10745.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"issuesOrigin": "private",
"title": "Cells pasted from clipboard's tables won't contain unnecessary line breaks",
"type": "fixed",
"issueOrPR": 10745,
"breaking": false,
"framework": "none"
}
69 changes: 69 additions & 0 deletions handsontable/src/utils/__tests__/parseTable.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,75 @@ describe('htmlToGridSettings', () => {
expect(config.mergeCells[1].rowspan).toBe(4);
});

it('should parse table with long text properly', () => {
/* eslint-disable no-irregular-whitespace */
const htmlToParse = `
<table>
<tr>
<td>
<p><span>Some very long text with no line breaks inside table
cell. Some very long text with no line breaks</span></p>
<p><span>&nbsp;</span></p>
<p><span>&nbsp;</span></p>
<p><span>ins table cell. Some very long text with no line breaks
inside table cell. Some very long text with no line breaks inside table cell.
Some very long text with no line breaks inside table cell. Some very long
text with no line breaks inside table cell. Some very long text with no line
breaks inside table cell. Some very long text with no line breaks inside
table cell. Some very long text with no line breaks inside table cell. Some
very long text with no line breaks inside table cell. Some very long text
with no line breaks inside table cell. Some very long text with no line
breaks inside table cell. Some very long text with no line breaks inside
table cell. Some very long text with no line breaks inside table cell. Some
very long text with no line breaks inside table cell. Some very long text
with no line breaks inside table cell. Some very long text with no line
breaks inside table cell. Some very long text with no line breaks inside
table cell. Some very long text with no line breaks inside table cell. Some
very long text with no line breaks inside table cell. Some very long text
with no line breaks inside table cell. Some very long text with no line
breaks inside table cell. Some very long text with no line breaks inside
table cell. Some very long text with no line breaks inside table cell.</span></p>
</td>
</tr>
<tr>
<td>
<p><span>Another very long text with no line breaks inside table
cell. <span>       </span>Some very long text with
no line breaks <span>     </span>o line breo line
breo line breo line breo line bre</span></p>
<p><span>&nbsp;</span></p>
<p><span>NEW LINE</span></p>
</td>
</tr>
</table>`;
/* eslint-enable */

const config = htmlToGridSettings(htmlToParse);

expect(config.data).toEqual([[
'Some very long text with no line breaks inside table cell. Some very long text with no line breaks' +
'\n\n\n' +
'ins table cell. Some very long text with no line breaks inside table cell. Some very long text with no line ' +
'breaks inside table cell. Some very long text with no line breaks inside table cell. Some very long text with ' +
'no line breaks inside table cell. Some very long text with no line breaks inside table cell. Some very long ' +
'text with no line breaks inside table cell. Some very long text with no line breaks inside table cell. Some ' +
'very long text with no line breaks inside table cell. Some very long text with no line breaks inside table ' +
'cell. Some very long text with no line breaks inside table cell. Some very long text with no line breaks ' +
'inside table cell. Some very long text with no line breaks inside table cell. Some very long text with no ' +
'line breaks inside table cell. Some very long text with no line breaks inside table cell. Some very long ' +
'text with no line breaks inside table cell. Some very long text with no line breaks inside table cell. Some ' +
'very long text with no line breaks inside table cell. Some very long text with no line breaks inside table ' +
'cell. Some very long text with no line breaks inside table cell. Some very long text with no line breaks ' +
'inside table cell. Some very long text with no line breaks inside table cell. Some very long text with no ' +
'line breaks inside table cell.'
], [
'Another very long text with no line breaks inside table cell. Some very long text with no line ' +
'breaks o line breo line breo line breo line breo line bre' +
'\n\n' +
'NEW LINE'
]]);
});

describe('nestedHeaders', () => {
it('should parse nested headers from HTML table', () => {
const htmlToParse = [
Expand Down
10 changes: 9 additions & 1 deletion handsontable/src/utils/parseTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,16 @@ export function htmlToGridSettings(element, rootDocument = document) {
if (typeof checkElement === 'string') {
const escapedAdjacentHTML = checkElement.replace(/<td\b[^>]*?>([\s\S]*?)<\/\s*td>/g, (cellFragment) => {
const openingTag = cellFragment.match(/<td\b[^>]*?>/g)[0];
const paragraphRegexp = /<p.*?>/g;
const cellValue = cellFragment
.substring(openingTag.length, cellFragment.lastIndexOf('<')).replace(/(<(?!br)([^>]+)>)/gi, '');
.substring(openingTag.length, cellFragment.lastIndexOf('<'))
.trim() // Removing whitespaces from the start and the end of HTML fragment
.replaceAll(/\n\s+/g, ' ') // HTML tags may be split using multiple new lines and whitespaces
.replaceAll(paragraphRegexp, '\n') // Only paragraphs should split text using new line characters
.replace('\n', '') // First paragraph shouldn't start with new line characters
.replaceAll(/<\/(.*)>\s+$/mg, '</$1>') // HTML tags may end with whitespace.
.replace(/(<(?!br)([^>]+)>)/gi, '') // Removing HTML tags
.replaceAll(/^&nbsp;$/mg, ''); // Removing single &nbsp; characters separating new lines
const closingTag = '</td>';

return `${openingTag}${cellValue}${closingTag}`;
Expand Down