[FIX] web_editor, website: prevent drop elements next to editable media
In the past, it was possible to drop elements in non-editable areas. Commit [1] fixed the issue but then commit [2] added a solution to be able to edit a media element that is in a `o_not_editable` environment. Unfortunately, the solution makes it possible to drop elements next to the `o_editable_media` elements ignoring the editable context (ignoring the first fix). Steps to reproduce the issue: - Enter website edit mode - Drop a Team block in a page - Click on the Team block => The user is able to drop a "Text highlight" block next to the team member pictures. This commit - reverts the commit [1] because in the meantime, the commit [3] fixed the issue. - fixes the Team block issue. - fixes the filterFunc for the drop-in. - adds a test to ensure the issue doesn't come back. [1]: https://github.com/odoo/odoo/commit/67924648676b37898aedd86bc32868299aee542c [2]: https://github.com/odoo/odoo/commit/580f1b77ce0b96b7efbf83a0ccdf6979bbf0e904 [3]: https://github.com/odoo/odoo/commit/ae7452f18dbd6ed56dbf883ae8495382b336aa78 opw-3536227 closes odoo/odoo#144806 X-original-commit: 9b4c2498b8fa2bc0aca604b6256e6c805b9b4c10 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> Signed-off-by: Guillaume Dieleman (gdi) <gdi@odoo.com>
This commit is contained in:
@@ -2423,7 +2423,7 @@ var SnippetsMenu = Widget.extend({
|
||||
$selectorSiblings = $(unique(($selectorSiblings || $()).add($selectorChildren.children()).get()));
|
||||
}
|
||||
|
||||
var noDropZonesSelector = '[data-invisible="1"], .o_we_no_overlay, :not(:visible), :not(:o_editable)';
|
||||
var noDropZonesSelector = '[data-invisible="1"], .o_we_no_overlay, :not(:visible)';
|
||||
if ($selectorSiblings) {
|
||||
$selectorSiblings.not(`.oe_drop_zone, .oe_drop_clone, ${noDropZonesSelector}`).each(function () {
|
||||
var data;
|
||||
@@ -2835,6 +2835,13 @@ var SnippetsMenu = Widget.extend({
|
||||
_computeSelectorFunctions: function (selector, exclude, target, noCheck, isChildren, excludeParent) {
|
||||
var self = this;
|
||||
|
||||
// TODO in master: FOR_DROP should be a param of the function.
|
||||
const forDropID = 'FOR_DROP';
|
||||
const forDrop = exclude && exclude.startsWith(forDropID);
|
||||
if (forDrop) {
|
||||
exclude = exclude.substring(forDropID.length);
|
||||
}
|
||||
|
||||
// The `:not(.o_editable_media)` part is handled outside of the selector
|
||||
// (see filterFunc).
|
||||
// Note: the `:not([contenteditable="true"])` part was there for that
|
||||
@@ -2856,10 +2863,19 @@ var SnippetsMenu = Widget.extend({
|
||||
// When noCheck is true, we only check the exclude.
|
||||
return true;
|
||||
}
|
||||
// `o_editable_media` bypasses the `o_not_editable` class.
|
||||
if (this.classList.contains('o_editable_media')) {
|
||||
// `o_editable_media` bypasses the `o_not_editable` class except for
|
||||
// drag & drop.
|
||||
if (!forDrop && this.classList.contains('o_editable_media')) {
|
||||
return weUtils.shouldEditableMediaBeEditable(this);
|
||||
}
|
||||
if (forDrop && !isChildren) {
|
||||
// it's a drop-in.
|
||||
return !$(this)
|
||||
.is('.o_not_editable :not([contenteditable="true"]), .o_not_editable');
|
||||
}
|
||||
if (isChildren) {
|
||||
return !$(this).is('.o_not_editable *');
|
||||
}
|
||||
return !$(this)
|
||||
.is('.o_not_editable:not(.s_social_media) :not([contenteditable="true"])');
|
||||
};
|
||||
@@ -2956,8 +2972,8 @@ var SnippetsMenu = Widget.extend({
|
||||
'base_target': target,
|
||||
'selector': self._computeSelectorFunctions(selector, exclude, target, noCheck),
|
||||
'$el': $style,
|
||||
'drop-near': $style.data('drop-near') && self._computeSelectorFunctions($style.data('drop-near'), '', false, noCheck, true, excludeParent),
|
||||
'drop-in': $style.data('drop-in') && self._computeSelectorFunctions($style.data('drop-in'), '', false, noCheck),
|
||||
'drop-near': $style.data('drop-near') && self._computeSelectorFunctions($style.data('drop-near'), 'FOR_DROP', false, noCheck, true, excludeParent),
|
||||
'drop-in': $style.data('drop-in') && self._computeSelectorFunctions($style.data('drop-in'), 'FOR_DROP', false, noCheck),
|
||||
'drop-exclude-ancestor': this.dataset.dropExcludeAncestor,
|
||||
'drop-lock-within': this.dataset.dropLockWithin,
|
||||
'data': Object.assign({string: $style.attr('string')}, $style.data()),
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import wTourUtils from '@website/js/tours/tour_utils';
|
||||
|
||||
wTourUtils.registerWebsitePreviewTour("test_drag_and_drop_on_non_editable", {
|
||||
test: true,
|
||||
url: "/",
|
||||
edition: true,
|
||||
}, () => [
|
||||
wTourUtils.dragNDrop({
|
||||
id: "s_company_team",
|
||||
name: "Team",
|
||||
}),
|
||||
{
|
||||
content: "Click on an editable media in non editable env.",
|
||||
trigger: "iframe .s_company_team .o_not_editable > .o_editable_media",
|
||||
},
|
||||
{
|
||||
content: "Verify that the Replace options is in the editor.",
|
||||
trigger: "we-button[data-replace-media]",
|
||||
isCheck: true,
|
||||
},
|
||||
wTourUtils.goBackToBlocks(),
|
||||
Object.assign(wTourUtils.dragNDrop({
|
||||
id: "s_text_highlight",
|
||||
name: "Text Highlight",
|
||||
}), {
|
||||
content: "Drag and drop the Text Highlight building block next to the Team block media.",
|
||||
run: "drag_and_drop_native iframe .s_company_team .o_not_editable > .o_editable_media",
|
||||
}),
|
||||
{
|
||||
content: "Verify that the Text Highlight building block isn't in a non editable element.",
|
||||
trigger: "iframe .s_company_team :not(.o_not_editable) > .s_text_highlight",
|
||||
isCheck: true,
|
||||
},
|
||||
]);
|
||||
@@ -95,3 +95,6 @@ class TestSnippets(HttpCase):
|
||||
website.cookies_bar = True
|
||||
self.start_tour(self.env['website'].get_client_action_url('/'), 'snippet_popup_and_scrollbar', login='admin')
|
||||
self.start_tour(self.env['website'].get_client_action_url('/'), 'snippet_popup_and_animations', login='admin')
|
||||
|
||||
def test_drag_and_drop_on_non_editable(self):
|
||||
self.start_tour(self.env['website'].get_client_action_url('/'), 'test_drag_and_drop_on_non_editable', login='admin')
|
||||
|
||||
Reference in New Issue
Block a user