From 51e4ac9e09ccbfcbb23a7a61ed2047f85b74fb39 Mon Sep 17 00:00:00 2001 From: Deependra Solanki Date: Tue, 12 Dec 2023 11:06:23 +0530 Subject: [PATCH] [FIX] web_editor: properly restore cursor in setTag Commit [1] introduces an approach to preserve the cursor in `setTag` when new node is inserted. It used `setStart` at `firstLeaf` of `startContainer` and used offset of the `startContainer` similarly for `endContainer` which is incorrect and would throw traceback regarding no child at that offset. This commit fix it by getting the correct startContainer and endContainer when new node is created. [1]: d04e32c task-3245819 X-original-commit: d9095d277e4dbfa318ff6ddd2692dbb3c71e4775 Part-of: odoo/odoo#151752 --- .../odoo-editor/src/commands/commands.js | 19 +++++++++++++------ .../odoo-editor/test/spec/format.test.js | 7 +++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js index 1285f26a4d8..9110aee1b7d 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/commands/commands.js @@ -49,8 +49,6 @@ import { isVisibleTextNode, getCursorDirection, resetOuids, - firstLeaf, - lastLeaf, FONT_SIZE_CLASSES, TEXT_STYLE_CLASSES, } from '../utils/utils.js'; @@ -333,7 +331,9 @@ export const editorCommands = { !descendants(block).some(descendant => selectedBlocks.includes(descendant)) && block.isContentEditable )); - const [startContainer, startOffset, endContainer, endOffset] = [firstLeaf(range.startContainer), range.startOffset, lastLeaf(range.endContainer), range.endOffset]; + let { startContainer, startOffset, endContainer, endOffset } = range; + const startContainerChild = startContainer.firstChild; + const endContainerChild = endContainer.lastChild; for (const block of deepestSelectedBlocks) { if ( ['P', 'PRE', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI', 'BLOCKQUOTE'].includes( @@ -372,10 +372,17 @@ export const editorCommands = { children.forEach(child => newBlock.appendChild(child)); } } + const isContextBlock = container => ['TD', 'DIV', 'LI'].includes(container.nodeName); + if (!startContainer.isConnected || isContextBlock(startContainer)) { + startContainer = startContainerChild.parentNode; + } + if (!endContainer.isConnected || isContextBlock(endContainer)) { + endContainer = endContainerChild.parentNode; + } const newRange = new Range(); - newRange.setStart(startContainer,startOffset); - newRange.setEnd(endContainer,endOffset); - getDeepRange(editor.editable, { range: newRange, select: true, }); + newRange.setStart(startContainer, startOffset); + newRange.setEnd(endContainer, endOffset); + getDeepRange(editor.editable, { range: newRange, select: true }); editor.historyStep(); }, diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/format.test.js b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/format.test.js index 67a4af6bd79..f9314b5631f 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/format.test.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/test/spec/format.test.js @@ -1199,6 +1199,13 @@ describe('setTagName', () => { contentAfter: '
[]a
b
c
', }); }); + it('should turn a paragraph into pre preserving the cursor position', async () => { + await testEditor(BasicEditor, { + contentBefore: '

abcd
[]

', + stepFunction: editor => editor.execCommand('setTag', 'pre'), + contentAfter: '
abcd
[]
', + }); + }); }); describe('to blockquote', () => { it('should turn a blockquote into a paragraph', async () => {