diff --git a/addons/website/static/src/js/content/menu.js b/addons/website/static/src/js/content/menu.js
index e8147d7e984..aaf6883f76f 100644
--- a/addons/website/static/src/js/content/menu.js
+++ b/addons/website/static/src/js/content/menu.js
@@ -516,11 +516,24 @@ publicWidget.registry.hoverableDropdown = animations.Animation.extend({
* @override
*/
start: function () {
+ if (this.editableMode) {
+ this._onPageClick = this._onPageClick.bind(this);
+ this.el.closest('#wrapwrap').addEventListener('click', this._onPageClick, {capture: true});
+ }
this.$dropdownMenus = this.$el.find('.dropdown-menu');
this.$dropdownToggles = this.$el.find('.dropdown-toggle');
this._dropdownHover();
return this._super.apply(this, arguments);
},
+ /**
+ * @override
+ */
+ destroy() {
+ if (this.editableMode) {
+ this.el.closest('#wrapwrap').removeEventListener('click', this._onPageClick, {capture: true});
+ }
+ return this._super.apply(this, arguments);
+ },
//--------------------------------------------------------------------------
// Private
@@ -539,6 +552,16 @@ publicWidget.registry.hoverableDropdown = animations.Animation.extend({
this.$dropdownMenus.css('top', '');
}
},
+ /**
+ * Hides all opened dropdowns.
+ *
+ * @private
+ */
+ _hideDropdowns() {
+ for (const toggleEl of this.el.querySelectorAll('.dropdown-toggle.show')) {
+ Dropdown.getOrCreateInstance(toggleEl).hide();
+ }
+ },
//--------------------------------------------------------------------------
// Handlers
@@ -549,6 +572,12 @@ publicWidget.registry.hoverableDropdown = animations.Animation.extend({
* @param {Event} ev
*/
_onMouseEnter: function (ev) {
+ if (this.editableMode) {
+ // Do not handle hover if another dropdown is opened.
+ if (this.el.querySelector('.dropdown-toggle.show')) {
+ return;
+ }
+ }
// The user must click on the dropdown if he is on mobile (no way to
// hover) or if the dropdown is the (or in the) extra menu ('+').
if (config.device.size_class <= config.device.SIZES.SM ||
@@ -562,12 +591,29 @@ publicWidget.registry.hoverableDropdown = animations.Animation.extend({
* @param {Event} ev
*/
_onMouseLeave: function (ev) {
+ if (this.editableMode) {
+ // Cancel handling from view mode.
+ return;
+ }
if (config.device.size_class <= config.device.SIZES.SM ||
ev.currentTarget.closest('.o_extra_menu_items')) {
return;
}
Dropdown.getOrCreateInstance(ev.currentTarget.querySelector('.dropdown-toggle')).hide();
},
+ /**
+ * Called when the page is clicked anywhere.
+ * Closes the shown dropdown if the click is outside of it.
+ *
+ * @private
+ * @param {Event} ev
+ */
+ _onPageClick(ev) {
+ if (ev.target.closest('.dropdown-menu.show')) {
+ return;
+ }
+ this._hideDropdowns();
+ },
});
publicWidget.registry.HeaderMainCollapse = publicWidget.Widget.extend({
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index a29494515d2..5b5aae887a3 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -2232,6 +2232,15 @@ options.registry.HeaderNavbar = options.Class.extend({
// Public
//--------------------------------------------------------------------------
+ /**
+ * @override
+ */
+ async start() {
+ await this._super(...arguments);
+ // TODO Remove in master.
+ const signInOptionEl = this.el.querySelector('[data-customize-website-views="portal.user_sign_in"]');
+ signInOptionEl.dataset.noPreview = 'true';
+ },
/**
* @private
*/
diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml
index 340b341c03c..2e6712530d2 100644
--- a/addons/website/views/snippets/snippets.xml
+++ b/addons/website/views/snippets/snippets.xml
@@ -928,7 +928,7 @@
On Click
-
+