You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop: Fixes #8476: Text that is pasted in Rich Text editor had extra new lines
This commit is contained in:
		| @@ -10,7 +10,31 @@ describe('htmlUtils', () => { | ||||
| 			], | ||||
| 			[ | ||||
| 				'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"/>', | ||||
|   | ||||
| @@ -176,13 +176,60 @@ export default new HtmlUtils(); | ||||
|  | ||||
| export function plainTextToHtml(plainText: string): string { | ||||
| 	const lines = plainText | ||||
| 		.replace(/[\n\r]/g, '\n') | ||||
| 		.replace(/\r\n/g, '\n') | ||||
| 		.split('\n'); | ||||
|  | ||||
| 	const lineOpenTag = lines.length > 1 ? '<p>' : ''; | ||||
| 	const lineCloseTag = lines.length > 1 ? '</p>' : ''; | ||||
| 	if (lines.length === 1) return escapeHtml(lines[0]); | ||||
|  | ||||
| 	return lines | ||||
| 		.map(line => lineOpenTag + escapeHtml(line) + lineCloseTag) | ||||
| 		.join(''); | ||||
| 	// Step 1: Merge adjacent lines into paragraphs, with each line separated by | ||||
| 	// '<br/>'. So 'one\ntwo' will become '<p>one</br>two</p>' | ||||
|  | ||||
| 	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(''); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user