Skip to content
Snippets Groups Projects
Commit dfcc3abe authored by Antoine Guenet's avatar Antoine Guenet
Browse files

[FIX] web_editor: properly paste pre in pre


Commit [1] attempted to fix unexpected behavior when copy-pasting from a
<pre> to a <pre>, where the pasted text was smaller the intended, and
preceded and followed by new lines. The chosen approach had uninteded
side effects though as it removed any empty paragraph after the <pre>.
The source of the issue it tried to fix was that the pasted <pre> was
inserted as a new <pre>, splitting the existing element in two in the
process, instead of simply inserting the text content.

[1] 449cacfe

task-3086603

closes odoo/odoo#108437

Signed-off-by: default avatarDavid Monjoie (dmo) <dmo@odoo.com>
parent 722cf3bf
Branches
Tags
No related merge requests found
......@@ -20,7 +20,6 @@ import {
isBlock,
isColorGradient,
isContentTextNode,
isEmptyBlock,
isSelectionFormat,
isShrunkBlock,
isVisible,
......@@ -46,6 +45,7 @@ import {
getRowIndex,
parseHTML,
formatSelection,
getDeepestPosition,
} from '../utils/utils.js';
const TEXT_CLASSES_REGEX = /\btext-[^\s]*\b/g;
......@@ -175,10 +175,16 @@ export const editorCommands = {
container.replaceChildren(...container.firstChild.childNodes);
}
startNode = startNode || editor.document.getSelection().anchorNode;
// In case the html inserted is all contained in a single root <p> or <li>
// tag, we take the all content of the <p> or <li> and avoid inserting the
// <p> or <li>.
if (container.childElementCount === 1 && (container.firstChild.nodeName === 'P' || container.firstChild.nodeName === 'LI')) {
// <p> or <li>. The same is true for a <pre> inside a <pre>.
if (container.childElementCount === 1 && (
container.firstChild.nodeName === 'P' ||
container.firstChild.nodeName === 'LI' ||
container.firstChild.nodeName === 'PRE' && closestElement(startNode, 'pre')
)) {
const p = container.firstElementChild;
container.replaceChildren(...p.childNodes);
} else if (container.childElementCount > 1) {
......@@ -194,7 +200,6 @@ export const editorCommands = {
}
}
startNode = startNode || editor.document.getSelection().anchorNode;
if (startNode.nodeType === Node.ELEMENT_NODE) {
if (selection.anchorOffset === 0) {
const textNode = editor.document.createTextNode('');
......@@ -268,9 +273,6 @@ export const editorCommands = {
if (offset) {
const [left, right] = splitElement(currentNode.parentElement, offset);
currentNode = insertBefore ? right : left;
if (isEmptyBlock(right)) {
right.remove();
}
} else {
currentNode = currentNode.parentElement;
}
......
......@@ -72,6 +72,24 @@ describe('insert HTML', () => {
contentAfter: '<p>ab</p><p>c</p><p>d[]e<br></p>',
});
});
it('should keep a paragraph after a div block', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>[]<br></p>',
stepFunction: async editor => {
await editor.execCommand('insert', parseHTML('<div><p>content</p></div>'));
},
contentAfter: '<div><p>content</p></div><p>[]<br></p>',
});
});
it('should not split a pre to insert another pre but just insert the text', async () => {
await testEditor(BasicEditor, {
contentBefore: '<pre>abc[]<br>ghi</pre>',
stepFunction: async editor => {
await editor.execCommand('insert', parseHTML('<pre>def</pre>'));
},
contentAfter: '<pre>abcdef[]<br>ghi</pre>',
});
});
});
describe('not collapsed selection', () => {
it('should delete selection and insert html in its place', async () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment