mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: Fixes #8476: Text that is pasted in Rich Text editor had extra new lines
This commit is contained in:
parent
35f375d756
commit
b9659bb9c1
@ -10,7 +10,31 @@ describe('htmlUtils', () => {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'line 1\nline 2',
|
'line 1\nline 2',
|
||||||
'<p>line 1</p><p>line 2</p>',
|
'<p>line 1<br/>line 2</p>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'one\n\ntwo\nthree\n\nfour',
|
||||||
|
'<p>one</p><p>two<br/>three</p><p>four</p>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'\n\n',
|
||||||
|
'<br/><br/>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'\n\none',
|
||||||
|
'<br/><p>one</p>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'\none\ntwo\n',
|
||||||
|
'<p>one<br/>two</p>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'one\n\n\ntwo',
|
||||||
|
'<p>one</p><br/><p>two</p>',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'one\n\n\n\ntwo',
|
||||||
|
'<p>one</p><br/><br/><p>two</p>',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'<img onerror="http://downloadmalware.com"/>',
|
'<img onerror="http://downloadmalware.com"/>',
|
||||||
|
@ -176,13 +176,60 @@ export default new HtmlUtils();
|
|||||||
|
|
||||||
export function plainTextToHtml(plainText: string): string {
|
export function plainTextToHtml(plainText: string): string {
|
||||||
const lines = plainText
|
const lines = plainText
|
||||||
.replace(/[\n\r]/g, '\n')
|
.replace(/\r\n/g, '\n')
|
||||||
.split('\n');
|
.split('\n');
|
||||||
|
|
||||||
const lineOpenTag = lines.length > 1 ? '<p>' : '';
|
if (lines.length === 1) return escapeHtml(lines[0]);
|
||||||
const lineCloseTag = lines.length > 1 ? '</p>' : '';
|
|
||||||
|
|
||||||
return lines
|
// Step 1: Merge adjacent lines into paragraphs, with each line separated by
|
||||||
.map(line => lineOpenTag + escapeHtml(line) + lineCloseTag)
|
// '<br/>'. So 'one\ntwo' will become '<p>one</br>two</p>'
|
||||||
.join('');
|
|
||||||
|
const step1: string[] = [];
|
||||||
|
let currentLine = '';
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim();
|
||||||
|
if (!line) {
|
||||||
|
if (currentLine) {
|
||||||
|
step1.push(`<p>${currentLine}</p>`);
|
||||||
|
currentLine = '';
|
||||||
|
}
|
||||||
|
step1.push(line);
|
||||||
|
} else {
|
||||||
|
if (currentLine) {
|
||||||
|
currentLine += `<br/>${escapeHtml(line)}`;
|
||||||
|
} else {
|
||||||
|
currentLine = escapeHtml(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLine) step1.push(`<p>${currentLine}</p>`);
|
||||||
|
|
||||||
|
// Step 2: Convert the remaining empty lines to <br/> tags. Note that `n`
|
||||||
|
// successive empty lines should produced `n-1` <br/> tags. This makes more
|
||||||
|
// sense when looking at the tests.
|
||||||
|
|
||||||
|
const step2: string[] = [];
|
||||||
|
let newLineCount = 0;
|
||||||
|
for (let i = 0; i < step1.length; i++) {
|
||||||
|
const line = step1[i];
|
||||||
|
|
||||||
|
if (!line) {
|
||||||
|
newLineCount++;
|
||||||
|
if (newLineCount >= 2) step2.push('');
|
||||||
|
} else {
|
||||||
|
newLineCount = 0;
|
||||||
|
step2.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Actually convert the empty lines to <br/> tags
|
||||||
|
|
||||||
|
const step3: string[] = [];
|
||||||
|
for (const line of step2) {
|
||||||
|
step3.push(line ? line : '<br/>');
|
||||||
|
}
|
||||||
|
|
||||||
|
return step3.join('');
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user