diff --git a/addons/web/static/src/legacy/js/libs/bootstrap.js b/addons/web/static/src/legacy/js/libs/bootstrap.js index 48cb13c50fa..53027e2fde3 100644 --- a/addons/web/static/src/legacy/js/libs/bootstrap.js +++ b/addons/web/static/src/legacy/js/libs/bootstrap.js @@ -131,3 +131,20 @@ ScrollSpy.prototype._process = function () { this._activate(this._targets[0]); } }; + +/** + * With bootstrap 5, navigation elements must be in the DOM and be visible. + * Since in the website editor, the user can hide the table of content block in + * many different ways, it happens that the navigation element is no longer + * found by bootstrap. We don't want to dispose scrollspy everywhere the block + * could be hidden. So this patch imitates the behavior of bootstrap 4.X by not + * causing an error if the navigation element is not found. + */ +const bootstrapSpyActivateFunction = ScrollSpy.prototype._activate; +ScrollSpy.prototype._activate = function (target) { + const element = document.querySelector(`[href="${target}"]`); + if (!element || $(element).is(':hidden')) { + return; + } + bootstrapSpyActivateFunction.apply(this, arguments); +}; diff --git a/addons/website/static/tests/tours/snippet_table_of_content.js b/addons/website/static/tests/tours/snippet_table_of_content.js index 5bcc42f66ce..e1ef7e43ea0 100644 --- a/addons/website/static/tests/tours/snippet_table_of_content.js +++ b/addons/website/static/tests/tours/snippet_table_of_content.js @@ -38,4 +38,46 @@ wTourUtils.registerWebsitePreviewTour('snippet_table_of_content', { checkTOCNavBar(1, 0), scrollToHeading(3), checkTOCNavBar(1, 1), + wTourUtils.clickOnEdit(), + { + content: "Click on the first TOC's title", + trigger: 'iframe .s_table_of_content:eq(0) h1', + }, + { + content: "Hide the first TOC on mobile", + trigger: '[data-toggle-device-visibility="no_mobile"]', + }, + { + content: "Click on the second TOC's title", + trigger: 'iframe .s_table_of_content:eq(1) h1', + }, + { + content: "Hide the second TOC on desktop", + trigger: '[data-toggle-device-visibility="no_desktop"]', + }, + ...wTourUtils.clickOnSave(), + { + content: "Check that we have the good TOC on desktop", + trigger: 'iframe .s_table_of_content.o_snippet_mobile_invisible', + run: () => { + if ($(document.querySelector('iframe .s_table_of_content.o_snippet_desktop_invisible')) + .is(':visible')) { + console.error('The mobile TOC should not be visible on desktop'); + } + }, + }, + { + content: "Toggle the mobile view", + trigger: '.o_mobile_preview', + }, + { + content: "Check that we have the good TOC on mobile", + trigger: 'iframe .s_table_of_content.o_snippet_desktop_invisible', + run: () => { + if ($(document.querySelector('iframe .s_table_of_content.o_snippet_mobile_invisible')) + .is(':visible')) { + console.error('The desktop TOC should not be visible on mobile'); + } + }, + }, ]);