diff --git a/addons/website/static/src/snippets/s_table_of_content/options.js b/addons/website/static/src/snippets/s_table_of_content/options.js index 937366c59cf..f50f7ebe091 100644 --- a/addons/website/static/src/snippets/s_table_of_content/options.js +++ b/addons/website/static/src/snippets/s_table_of_content/options.js @@ -9,6 +9,7 @@ options.registry.TableOfContent = options.Class.extend({ */ start: function () { this.targetedElements = 'h1, h2'; + this.oldHeadingsEls = []; const $headings = this.$target.find(this.targetedElements); if ($headings.length > 0) { this._generateNav(); @@ -77,10 +78,23 @@ options.registry.TableOfContent = options.Class.extend({ */ _generateNav: function (ev) { this.options.wysiwyg && this.options.wysiwyg.odooEditor.unbreakableStepUnactive(); + const $headings = this.$target.find(this.targetedElements); + const areHeadingsEqual = this.oldHeadingsEls.length === $headings.length + && this.oldHeadingsEls.every((el, i) => el.isEqualNode($headings[i])); + if (areHeadingsEqual) { + // If the content of the navbar before the change of the DOM is + // equal to the content of the navbar after the change of the DOM, + // then there is no need to regenerate the navbar. + // This is especially important as to regenerate it, we also have + // to restart scrollSpy, which is done by restarting widgets. But + // restarting all widgets inside the ToC would certainly lead to + // DOM changes... which would then regenerate the navbar and lead to + // an infinite loop. + return; + } // We dispose the scrollSpy because the navbar will be updated. this._disposeScrollSpy(); const $nav = this.$target.find('.s_table_of_content_navbar'); - const $headings = this.$target.find(this.targetedElements); $nav.empty(); _.each($headings, el => { const $el = $(el); @@ -94,6 +108,7 @@ options.registry.TableOfContent = options.Class.extend({ }); const exception = (tocEl) => !tocEl.querySelector('.s_table_of_content_navbar a'); this._activateScrollSpy(exception); + this.oldHeadingsEls = [...($headings.clone())]; }, });