From 19d7c75f895a0fcf83221aebc37f161bf98716db Mon Sep 17 00:00:00 2001 From: Raphael Sanchez Date: Fri, 28 Aug 2026 12:32:50 +0200 Subject: [PATCH 1/4] fix: Init frontend TOC on DOMContentLoaded --- src/view.js | 62 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/view.js b/src/view.js index f78e3fe..5dc9080 100644 --- a/src/view.js +++ b/src/view.js @@ -2,7 +2,7 @@ 'use strict'; class TOC { - constructor( tocNodes ) { + constructor(tocNodes) { this.toc = tocNodes; this.tocLinks = this.toc.querySelectorAll( @@ -14,17 +14,17 @@ class TOC { this.headingsScrollObserver ); - if ( this.tocLinks.length ) { - const idsFromLinks = Array.from( this.tocLinks ).map( ( el ) => - el.getAttribute( 'href' ).replace( '#', '' ) + if (this.tocLinks.length) { + const idsFromLinks = Array.from(this.tocLinks).map((el) => + el.getAttribute('href').replace('#', '') ); - if ( idsFromLinks.length ) { - for ( const id of idsFromLinks ) { - const heading = document.getElementById( id ); - if ( heading ) { - this.headings.push( heading ); - observer.observe( heading ); + if (idsFromLinks.length) { + for (const id of idsFromLinks) { + const heading = document.getElementById(id); + if (heading) { + this.headings.push(heading); + observer.observe(heading); } } } @@ -37,17 +37,17 @@ class TOC { * @param {HTMLElement} el * @return {boolean} true if the element is in the viewport */ - isElementInViewport = ( el ) => { + isElementInViewport = (el) => { const rect = el.getBoundingClientRect(); return ( rect.top >= -1 && rect.left >= 0 && rect.bottom <= - ( window.innerHeight || - document.documentElement.clientHeight ) && + (window.innerHeight || + document.documentElement.clientHeight) && rect.right <= - ( window.innerWidth || document.documentElement.clientWidth ) + (window.innerWidth || document.documentElement.clientWidth) ); }; @@ -56,34 +56,34 @@ class TOC { * * @param {IntersectionObserverEntry[]} entries */ - headingsScrollObserver = ( entries ) => { + headingsScrollObserver = (entries) => { // Get all entries that have just come into the viewport const allHeadings = new Set( entries - .filter( ( entry ) => entry.isIntersecting === true ) - .map( ( entry ) => entry.target ) + .filter((entry) => entry.isIntersecting === true) + .map((entry) => entry.target) ); let currentHeading; - for ( let i = 0; i < this.headings.length; i++ ) { - currentHeading = this.headings[ i ]; + for (let i = 0; i < this.headings.length; i++) { + currentHeading = this.headings[i]; // If the section is in the viewport or it has just intersected, set it as active if ( - this.isElementInViewport( currentHeading ) || - allHeadings.has( currentHeading ) + this.isElementInViewport(currentHeading) || + allHeadings.has(currentHeading) ) { // Disable all links and active the current one. - for ( const link of this.tocLinks ) { + for (const link of this.tocLinks) { link.parentElement.setAttribute( 'data-toc-active', 'false' ); } const link = this.toc.querySelector( - `a[href="#${ currentHeading.id }"]` + `a[href="#${currentHeading.id}"]` ); - if ( link ) { + if (link) { link.parentElement.setAttribute( 'data-toc-active', 'true' @@ -95,11 +95,17 @@ class TOC { }; } -window.addEventListener( 'load', function () { +function initTableOfContent() { const tocBlocks = document.querySelectorAll( '.blockparty-table-of-content' ); - for ( let i = 0; i < tocBlocks.length; i++ ) { - new TOC( tocBlocks[ i ] ); + for (let i = 0; i < tocBlocks.length; i++) { + new TOC(tocBlocks[i]); } -} ); +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initTableOfContent); +} else { + initTableOfContent(); +} From f26cb08e20b3df1db84940941449ab8b04701479 Mon Sep 17 00:00:00 2001 From: Raphael Sanchez Date: Fri, 28 Aug 2026 14:05:44 +0200 Subject: [PATCH 2/4] refactor: Clean up code formatting in block.json and view.js --- src/block.json | 4 +--- src/view.js | 56 +++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/block.json b/src/block.json index f5fe0c3..a04491e 100644 --- a/src/block.json +++ b/src/block.json @@ -24,9 +24,7 @@ }, "levels": { "type": "array", - "default": [ - 2 - ] + "default": [ 2 ] }, "sticky": { "type": "boolean", diff --git a/src/view.js b/src/view.js index 5dc9080..ee05592 100644 --- a/src/view.js +++ b/src/view.js @@ -2,7 +2,7 @@ 'use strict'; class TOC { - constructor(tocNodes) { + constructor( tocNodes ) { this.toc = tocNodes; this.tocLinks = this.toc.querySelectorAll( @@ -14,17 +14,17 @@ class TOC { this.headingsScrollObserver ); - if (this.tocLinks.length) { - const idsFromLinks = Array.from(this.tocLinks).map((el) => - el.getAttribute('href').replace('#', '') + if ( this.tocLinks.length ) { + const idsFromLinks = Array.from( this.tocLinks ).map( ( el ) => + el.getAttribute( 'href' ).replace( '#', '' ) ); - if (idsFromLinks.length) { - for (const id of idsFromLinks) { - const heading = document.getElementById(id); - if (heading) { - this.headings.push(heading); - observer.observe(heading); + if ( idsFromLinks.length ) { + for ( const id of idsFromLinks ) { + const heading = document.getElementById( id ); + if ( heading ) { + this.headings.push( heading ); + observer.observe( heading ); } } } @@ -37,17 +37,17 @@ class TOC { * @param {HTMLElement} el * @return {boolean} true if the element is in the viewport */ - isElementInViewport = (el) => { + isElementInViewport = ( el ) => { const rect = el.getBoundingClientRect(); return ( rect.top >= -1 && rect.left >= 0 && rect.bottom <= - (window.innerHeight || - document.documentElement.clientHeight) && + ( window.innerHeight || + document.documentElement.clientHeight ) && rect.right <= - (window.innerWidth || document.documentElement.clientWidth) + ( window.innerWidth || document.documentElement.clientWidth ) ); }; @@ -56,34 +56,34 @@ class TOC { * * @param {IntersectionObserverEntry[]} entries */ - headingsScrollObserver = (entries) => { + headingsScrollObserver = ( entries ) => { // Get all entries that have just come into the viewport const allHeadings = new Set( entries - .filter((entry) => entry.isIntersecting === true) - .map((entry) => entry.target) + .filter( ( entry ) => entry.isIntersecting === true ) + .map( ( entry ) => entry.target ) ); let currentHeading; - for (let i = 0; i < this.headings.length; i++) { - currentHeading = this.headings[i]; + for ( let i = 0; i < this.headings.length; i++ ) { + currentHeading = this.headings[ i ]; // If the section is in the viewport or it has just intersected, set it as active if ( - this.isElementInViewport(currentHeading) || - allHeadings.has(currentHeading) + this.isElementInViewport( currentHeading ) || + allHeadings.has( currentHeading ) ) { // Disable all links and active the current one. - for (const link of this.tocLinks) { + for ( const link of this.tocLinks ) { link.parentElement.setAttribute( 'data-toc-active', 'false' ); } const link = this.toc.querySelector( - `a[href="#${currentHeading.id}"]` + `a[href="#${ currentHeading.id }"]` ); - if (link) { + if ( link ) { link.parentElement.setAttribute( 'data-toc-active', 'true' @@ -99,13 +99,13 @@ function initTableOfContent() { const tocBlocks = document.querySelectorAll( '.blockparty-table-of-content' ); - for (let i = 0; i < tocBlocks.length; i++) { - new TOC(tocBlocks[i]); + for ( let i = 0; i < tocBlocks.length; i++ ) { + new TOC( tocBlocks[ i ] ); } } -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initTableOfContent); +if ( document.readyState === 'loading' ) { + document.addEventListener( 'DOMContentLoaded', initTableOfContent ); } else { initTableOfContent(); } From 04f790ca1f69c7fde7429ccfc67c8aeaafbfacd7 Mon Sep 17 00:00:00 2001 From: Raphael Sanchez Date: Fri, 28 Aug 2026 14:17:47 +0200 Subject: [PATCH 3/4] chore: release 1.0.6 --- .plugin-data | 2 +- CHANGELOG.md | 4 ++++ blockparty-table-of-content.php | 4 ++-- package.json | 2 +- src/block.json | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.plugin-data b/.plugin-data index 6c6f750..0be26ab 100644 --- a/.plugin-data +++ b/.plugin-data @@ -1,4 +1,4 @@ { - "version": "1.0.5", + "version": "1.0.6", "slug": "blockparty-table-of-content" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 804c126..c0a2194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.0.6 - 2026-08-28 + +* Fix frontend TOC initialization by waiting for DOMContentLoaded + ## 1.0.5 - 2026-06-25 * Rename plugin to "Blockparty Table of content" diff --git a/blockparty-table-of-content.php b/blockparty-table-of-content.php index 56ba6ca..7040626 100644 --- a/blockparty-table-of-content.php +++ b/blockparty-table-of-content.php @@ -4,7 +4,7 @@ * Description: A table of content block. * Requires at least: 6.0 * Requires PHP: 7.4 - * Version: 1.0.5 + * Version: 1.0.6 * Author: Be API Technical team * Author URI: https://beapi.fr * License: GPL-2.0-or-later @@ -16,7 +16,7 @@ namespace Beapi\Toc_Block; -define( 'BEAPI_TOC_BLOCK_VERSION', '1.0.5' ); +define( 'BEAPI_TOC_BLOCK_VERSION', '1.0.6' ); define( 'BEAPI_TOC_BLOCK_URL', plugin_dir_url( __FILE__ ) ); define( 'BEAPI_TOC_BLOCK_DIR', plugin_dir_path( __FILE__ ) ); define( 'BEAPI_TOC_BLOCK_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); diff --git a/package.json b/package.json index da9a8ac..8736265 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockparty-table-of-content", - "version": "1.0.5", + "version": "1.0.6", "description": "A table of content block.", "author": "Be API Technical team", "license": "GPL-2.0-or-later", diff --git a/src/block.json b/src/block.json index a04491e..e7c27d3 100644 --- a/src/block.json +++ b/src/block.json @@ -2,7 +2,7 @@ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "blockparty/table-of-content", - "version": "1.0.5", + "version": "1.0.6", "title": "Table of content", "category": "widgets", "icon": "editor-ul", From 901ec9453410d9f11861c609ff6cb6381fd0e278 Mon Sep 17 00:00:00 2001 From: Raphael Sanchez Date: Fri, 28 Aug 2026 15:20:13 +0200 Subject: [PATCH 4/4] update changelog in readme.txt --- readme.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index d3bba2e..029636b 100644 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Contributors: beapi Tags: block, table of content Tested up to: 6.5 -Stable tag: 1.0.5 +Stable tag: 1.0.6 License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -17,6 +17,9 @@ This plugin adds a block to the WordPress block editor that allows you to add a == Changelog == += 1.0.6 = +* Fix frontend TOC initialization by waiting for DOMContentLoaded + = 1.0.5 = * Rename plugin to "Blockparty Table of content" * Improve heading level selector in the block editor with an icon toggle group