diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 4ad0f8a2016..a886d3bc5c5 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -31,9 +31,11 @@ const { createDataURL, isGif, } = require('web_editor.image_processing'); +const OdooEditorLib = require('@web_editor/js/editor/odoo-editor/src/OdooEditor'); var qweb = core.qweb; var _t = core._t; +const preserveCursor = OdooEditorLib.preserveCursor; /** * @param {HTMLElement} el @@ -4624,7 +4626,9 @@ registry.layout_column = SnippetOptionWidget.extend({ const previousNbColumns = this.$('> .row').children().length; let $row = this.$('> .row'); if (!$row.length) { + const restoreCursor = preserveCursor(this.$target[0].ownerDocument); $row = this.$target.contents().wrapAll($('
')).parent().parent(); + restoreCursor(); } const nbColumns = parseInt(widgetValue); @@ -4634,7 +4638,9 @@ registry.layout_column = SnippetOptionWidget.extend({ // TODO: make this more generic in activate_snippet event handler. await new Promise(resolve => setTimeout(resolve)); if (nbColumns === 0) { + const restoreCursor = preserveCursor(this.$target[0].ownerDocument); $row.contents().unwrap().contents().unwrap(); + restoreCursor(); this.trigger_up('activate_snippet', {$snippet: this.$target}); } else if (previousNbColumns === 0) { this.trigger_up('activate_snippet', {$snippet: this.$('> .row').children().first()}); diff --git a/addons/website/static/tests/tours/snippet_editor_panel_options.js b/addons/website/static/tests/tours/snippet_editor_panel_options.js index 0045f7e02b5..0551a9cd29e 100644 --- a/addons/website/static/tests/tours/snippet_editor_panel_options.js +++ b/addons/website/static/tests/tours/snippet_editor_panel_options.js @@ -10,7 +10,9 @@ wTourUtils.registerEditionTour('snippet_editor_panel_options', { wTourUtils.dragNDrop({ id: 's_text_image', name: 'Text - Image', -}), { +}), +// Test keeping the text selection when using the width option. +{ content: "Click on the first paragraph.", trigger: 'iframe .s_text_image p', }, { @@ -42,7 +44,9 @@ wTourUtils.dragNDrop({ console.error("The paragraph text selection was lost."); } }, -}, { +}, +// Test the anchor option. +{ content: "Click on the anchor option", trigger: '#oe_snippets .snippet-option-anchor we-button', run() { @@ -73,4 +77,74 @@ wTourUtils.dragNDrop({ console.error('The anchor option does not target the correct snippet.'); } }, +}, +// Test keeping the text selection when adding columns to a snippet with none. +wTourUtils.goBackToBlocks(), +wTourUtils.dragNDrop({ + id: 's_text_block', + name: 'Text', +}), +{ + content: "Click on the first paragraph.", + trigger: 'iframe .s_text_block p', +}, { + content: "The text toolbar should be visible. The paragraph should be selected.", + trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container', + run() { + const iframeDocument = document.querySelector('.o_iframe').contentDocument; + const pText = iframeDocument.querySelector('.s_text_block p').textContent; + const selection = iframeDocument.getSelection().toString(); + if (pText !== selection) { + console.error("The paragraph was not correctly selected."); + } + }, +}, { + content: "Click on the columns option.", + trigger: '.snippet-option-layout_column we-select', +}, +{ + content: "Change the number of columns.", + trigger: '.snippet-option-layout_column [data-select-count="3"]', +}, { + content: "The snippet should have the correct number of columns.", + trigger: 'iframe .s_text_block .container > .row', + run() { + if (this.$anchor[0].childElementCount !== 3) { + console.error("The snippet does not have the correct number of columns"); + } + }, +}, { + content: "The text toolbar should still be visible, and the text still selected.", + trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container', + run() { + const iframeDocument = document.querySelector('.o_iframe').contentDocument; + const pText = iframeDocument.querySelector('.s_text_block p').textContent; + const selection = iframeDocument.getSelection().toString(); + if (pText !== selection) { + console.error("The paragraph text selection was lost."); + } + }, +}, +// Test keeping the text selection when removing all columns of a snippet. +{ + content: "Click on the columns option.", + trigger: '.snippet-option-layout_column we-select', +}, +{ + content: "Change the number of columns.", + trigger: '.snippet-option-layout_column [data-select-count="0"]', +}, { + content: "The snippet should have the correct number of columns.", + trigger: 'iframe .s_text_block .container:not(:has(.row))', +}, { + content: "The text toolbar should still be visible, and the text still selected.", + trigger: '#oe_snippets .o_we_customize_panel > #o_we_editor_toolbar_container', + run() { + const iframeDocument = document.querySelector('.o_iframe').contentDocument; + const pText = iframeDocument.querySelector('.s_text_block p').textContent; + const selection = iframeDocument.getSelection().toString(); + if (pText !== selection) { + console.error("The paragraph text selection was lost."); + } + }, }]);