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.");
+ }
+ },
}]);