[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] 449cacf task-3086603 closes odoo/odoo#109208 X-original-commit: dfcc3abe3396eaf764c3c3c8510b654649ed82f8 Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
@@ -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 () => {
|
||||
|
||||
Reference in New Issue
Block a user