From cb1ad42130b52334992aba2f10bb91798b23a7a6 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Wed, 13 Dec 2023 12:32:31 +0100 Subject: [PATCH] [FIX] website: make anchor links work in offcanvas mobile menu A anchor menu in the mobile offcanvas related to an element in the current page doesn't work in offcanvas: - The offcanvas doesn't close - The page doesn't scroll to the clicked location This is because the menu anchor navigation is hooked to use our own scrolling behavior instead of the browser one. Doing so, we preventDefault, which prevent the offcanvas menu to close itself when clicking on a anchor menu. This commit simply manually closes the offcanvas and once the closing animation is complete, starts our own smooth scrolling. It also targets the desktop offcanvas menu (when hamburger layout is selected) so it got a smoother UX: it closes then scrolls, instead of scrolling but not closing. Another possibility would have been to just close manually the offcanvas without a preventDefault and without a call to our custom scrolling method. Doing so, the browser would naturally scroll to the element while we close the offcanvas but it would be less elegant as you wouldn't see the scrolling animation. Note that the offcanvas was introduced with commit [1]. [1]: https://github.com/odoo/odoo/commit/bc13176de8d66bbdc1c536017b1f046c5fd31a86 opw-3604963 closes odoo/odoo#146907 X-original-commit: db881e66785a866319bd4980a9ae7b6393e55457 Signed-off-by: Quentin Smetz (qsm) --- addons/web/tooling/_eslintrc.json | 1 + .../src/js/content/snippets.animation.js | 19 +++++++++++++++++-- odoo/addons/test_lint/tests/eslintrc | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/addons/web/tooling/_eslintrc.json b/addons/web/tooling/_eslintrc.json index 92f7c655619..9ae39986a6f 100644 --- a/addons/web/tooling/_eslintrc.json +++ b/addons/web/tooling/_eslintrc.json @@ -60,6 +60,7 @@ "Collapse": "readonly", "Dropdown": "readonly", "Modal": "readonly", + "Offcanvas": "readonly", "Popover": "readonly", "Tooltip": "readonly" } diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 9c0844e44f5..5b3f6d60a64 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -1039,8 +1039,23 @@ registry.anchorSlide = publicWidget.Widget.extend({ if (!$anchor.length || !scrollValue) { return; } - ev.preventDefault(); - this._scrollTo($anchor, scrollValue); + + const offcanvasEl = this.el.closest('.offcanvas.o_navbar_mobile'); + if (offcanvasEl && offcanvasEl.classList.contains('show')) { + // Special case for anchors in offcanvas in mobile: we can't just + // _scrollTo() after preventDefault because preventDefault would + // prevent the offcanvas to be closed. The choice is then to close + // it ourselves manually and once it's fully closed, then start our + // own smooth scrolling. + ev.preventDefault(); + Offcanvas.getInstance(offcanvasEl).hide(); + offcanvasEl.addEventListener('hidden.bs.offcanvas', () => { + this._scrollTo($anchor, scrollValue); + }); + } else { + ev.preventDefault(); + this._scrollTo($anchor, scrollValue); + } }, }); diff --git a/odoo/addons/test_lint/tests/eslintrc b/odoo/addons/test_lint/tests/eslintrc index 20228f6eb5c..54f897808dd 100644 --- a/odoo/addons/test_lint/tests/eslintrc +++ b/odoo/addons/test_lint/tests/eslintrc @@ -46,6 +46,7 @@ "Collapse": "readonly", "Dropdown": "readonly", "Modal": "readonly", + "Offcanvas": "readonly", "Popover": "readonly", "Tooltip": "readonly" }